Decompiled source of PEAK Checkpoint Save v0.2.6

plugins/PEAK_Checkpoint_Save.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Peak.Network;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("PEAK_Checkpoint_Save")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.2.6.0")]
[assembly: AssemblyInformationalVersion("0.2.6")]
[assembly: AssemblyProduct("PEAK_Checkpoint_Save")]
[assembly: AssemblyTitle("PEAK_Checkpoint_Save")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.2.6.0")]
[module: UnverifiableCode]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[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 BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace PEAK_Checkpoint_Save
{
	[BepInPlugin("PEAK_Checkpoint_Save", "PEAK_Checkpoint_Save", "0.2.6")]
	public class Plugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(Campfire))]
		public static class Campfire_AutoSave_Patch
		{
			[HarmonyPatch("Interact_CastFinished")]
			[HarmonyPostfix]
			public static void AutoSaveOnCampfire(Campfire __instance)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				if ((int)__instance.advanceToSegment == 0 || RecentlyLitCampfire > Time.time)
				{
					return;
				}
				RecentlyLitCampfire = Time.time + 60f;
				if ((Object)(object)Instance == (Object)null)
				{
					Debug.LogError((object)"[Checkpoint_Save] Plugin.Instance is NULL! Autosave failed.");
					return;
				}
				((BaseUnityPlugin)Instance).Logger.LogInfo((object)"[Checkpoint_Save] Campfire lit → Autosave triggered.");
				if (PhotonNetwork.OfflineMode)
				{
					Instance.SavePlayerOffline();
				}
				else if (PhotonNetwork.IsMasterClient)
				{
					Instance.pv.RPC("RPC_RecentlyLitCampfire", (RpcTarget)1, Array.Empty<object>());
					Instance.SavePlayerCoop();
				}
				else
				{
					Instance.pv.RPC("RPC_RequestSave", (RpcTarget)2, Array.Empty<object>());
				}
			}
		}

		[HarmonyPatch(typeof(CharacterMovement))]
		[HarmonyPatch("CheckFallDamage")]
		internal class Patch_FallDamage_Protection
		{
			private static bool Prefix(CharacterMovement __instance)
			{
				if (Time.time < NoFallDamageUntil)
				{
					return false;
				}
				return true;
			}
		}

		[Serializable]
		public class SaveData
		{
			public int settingsVersion;

			public float posX;

			public float posY;

			public float posZ;

			public string sceneName;

			public Segment segment;

			public bool hasBackpack;

			public List<ushort> inventoryItemIds;

			public List<ushort> backpackItemIds;

			public float[] afflictions_current;
		}

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

			private object <>2__current;

			public SaveData data;

			public Plugin <>4__this;

			private int <i>5__2;

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

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

			[DebuggerHidden]
			public <JumpToMapSegment>d__46(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_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_004d: Expected I4, but got Unknown
				//IL_016b: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				Plugin plugin = <>4__this;
				Vector3 pos = default(Vector3);
				switch (num)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					Segment segment = data.segment;
					switch (segment - 1)
					{
					case 0:
						break;
					case 1:
						plugin.pv.RPC("RPC_RequestFalldamageProtection", (RpcTarget)0, Array.Empty<object>());
						MapHandler.JumpToSegment((Segment)2);
						goto end_IL_000f;
					case 2:
						plugin.pv.RPC("RPC_RequestFalldamageProtection", (RpcTarget)0, Array.Empty<object>());
						MapHandler.JumpToSegment((Segment)3);
						goto end_IL_000f;
					case 3:
						goto IL_00ef;
					default:
						goto end_IL_000f;
					}
					plugin.pv.RPC("RPC_RequestFalldamageProtection", (RpcTarget)0, Array.Empty<object>());
					MapHandler.JumpToSegment((Segment)1);
					<i>5__2 = 0;
					goto IL_009e;
				}
				case 1:
					<>1__state = -1;
					<i>5__2++;
					goto IL_009e;
				case 2:
					{
						<>1__state = -1;
						<i>5__2++;
						goto IL_013b;
					}
					IL_00ef:
					plugin.pv.RPC("RPC_RequestFalldamageProtection", (RpcTarget)0, Array.Empty<object>());
					MapHandler.JumpToSegment((Segment)3);
					<i>5__2 = 0;
					goto IL_013b;
					IL_013b:
					if (<i>5__2 < 60)
					{
						<>2__current = null;
						<>1__state = 2;
						return true;
					}
					pos.x = -0.91186905f;
					pos.y = 842.8689f;
					pos.z = 1713.6833f;
					((MonoBehaviour)plugin).StartCoroutine(plugin.TeleportToPosition(pos));
					break;
					IL_009e:
					if (<i>5__2 < 60)
					{
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					break;
					end_IL_000f:
					break;
				}
				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 <LoadInventoryDelayed>d__49 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Plugin <>4__this;

			private int <i>5__2;

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

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

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

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

			private bool MoveNext()
			{
				int num = <>1__state;
				Plugin plugin = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<i>5__2 = 0;
					break;
				case 1:
					<>1__state = -1;
					<i>5__2++;
					break;
				}
				if (<i>5__2 < 30)
				{
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				Player[] array = Object.FindObjectsByType<Player>((FindObjectsSortMode)0);
				foreach (Player val in array)
				{
					foreach (Character allCharacter in Character.AllCharacters)
					{
						if (!(NetworkingUtilities.UserId(allCharacter.player) == NetworkingUtilities.UserId(val)))
						{
							continue;
						}
						string playerSaveFile = plugin.GetPlayerSaveFile(NetworkingUtilities.UserId(allCharacter.player));
						SaveData saveData = null;
						try
						{
							string text = File.ReadAllText(playerSaveFile);
							saveData = JsonConvert.DeserializeObject<SaveData>(text);
						}
						catch
						{
							string text = null;
							saveData = null;
						}
						if (plugin.configInventory.Value && saveData != null)
						{
							plugin.LoadPlayerInventory(saveData, val, allCharacter);
							if (PhotonNetwork.IsMasterClient)
							{
								plugin.LoadBackpackFromSave(val, saveData);
							}
							if (!PhotonNetwork.OfflineMode && saveData.backpackItemIds != null && saveData.backpackItemIds.Count > 0)
							{
								try
								{
									PhotonView component = ((Component)val).GetComponent<PhotonView>();
									if ((Object)(object)component != (Object)null)
									{
										int[] array2 = new int[saveData.backpackItemIds.Count];
										for (int j = 0; j < array2.Length; j++)
										{
											array2[j] = saveData.backpackItemIds[j];
										}
										plugin.pv.RPC("RPC_ApplyBackpackFromSave", component.Owner, new object[2]
										{
											NetworkingUtilities.UserId(val),
											array2
										});
										((BaseUnityPlugin)plugin).Logger.LogInfo((object)("[Checkpoint_Save] Sent RPC_ApplyBackpackFromSave to " + NetworkingUtilities.UserId(val)));
									}
									else
									{
										((BaseUnityPlugin)plugin).Logger.LogWarning((object)"[Checkpoint_Save] LoadInventoryDelayed: Player has no PhotonView, cannot send backpack RPC.");
									}
								}
								catch (Exception ex)
								{
									((BaseUnityPlugin)plugin).Logger.LogWarning((object)("[Checkpoint_Save] LoadInventoryDelayed: failed to send backpack RPC: " + ex));
								}
							}
						}
						if (!plugin.configAfflictions.Value || saveData == null)
						{
							continue;
						}
						if (PhotonNetwork.OfflineMode)
						{
							try
							{
								CharacterAfflictions afflictions = allCharacter.refs.afflictions;
								if (saveData.afflictions_current != null && afflictions.currentStatuses != null && afflictions.currentStatuses.Length == saveData.afflictions_current.Length)
								{
									Array.Copy(saveData.afflictions_current, afflictions.currentStatuses, afflictions.currentStatuses.Length);
								}
							}
							catch
							{
							}
						}
						else
						{
							if (!PhotonNetwork.IsMasterClient || saveData.afflictions_current == null || saveData == null)
							{
								continue;
							}
							try
							{
								PhotonView component2 = ((Component)val).GetComponent<PhotonView>();
								if ((Object)(object)component2 != (Object)null)
								{
									plugin.pv.RPC("RPC_ApplyAfflictions", component2.Owner, new object[2]
									{
										NetworkingUtilities.UserId(val),
										saveData.afflictions_current
									});
								}
								else
								{
									((BaseUnityPlugin)plugin).Logger.LogWarning((object)"[Checkpoint_Save] LoadInventoryDelayed: Player has no PhotonView, cannot send afflictions RPC.");
								}
							}
							catch (Exception ex2)
							{
								((BaseUnityPlugin)plugin).Logger.LogWarning((object)("[Checkpoint_Save] LoadInventoryDelayed: failed to send afflictions RPC: " + ex2));
							}
						}
					}
				}
				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 <TeleportClientToHost>d__48 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Plugin <>4__this;

			private Vector3 <hostPos>5__2;

			private int <i>5__3;

			private List<Character>.Enumerator <>7__wrap3;

			private Character <ch>5__5;

			private float <startTime>5__6;

			private int <i>5__7;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 2)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>7__wrap3 = default(List<Character>.Enumerator);
				<ch>5__5 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0034: 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_0208: Unknown result type (might be due to invalid IL or missing references)
				//IL_0121: Unknown result type (might be due to invalid IL or missing references)
				//IL_0248: Unknown result type (might be due to invalid IL or missing references)
				//IL_014d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0161: Unknown result type (might be due to invalid IL or missing references)
				//IL_0166: Unknown result type (might be due to invalid IL or missing references)
				//IL_016b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0276: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
				//IL_0199: Unknown result type (might be due to invalid IL or missing references)
				//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					int num = <>1__state;
					Plugin plugin = <>4__this;
					switch (num)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<hostPos>5__2 = Character.localCharacter.Head;
						<i>5__3 = 0;
						goto IL_0073;
					case 1:
						<>1__state = -1;
						<i>5__3++;
						goto IL_0073;
					case 2:
						{
							<>1__state = -3;
							<i>5__7++;
							goto IL_02d1;
						}
						IL_0073:
						if (<i>5__3 < 60)
						{
							<>2__current = null;
							<>1__state = 1;
							return true;
						}
						<>7__wrap3 = Character.AllCharacters.GetEnumerator();
						<>1__state = -3;
						goto IL_0308;
						IL_02e4:
						if (Time.time - <startTime>5__6 < (float)plugin.configTeleportTryTime.Value)
						{
							if (Mathf.Abs(<ch>5__5.Head.y - <hostPos>5__2.y) > plugin.configTeleportYOffset.Value)
							{
								try
								{
									Vector3 val = <hostPos>5__2 + new Vector3(0f, 0.5f, 0f);
									if ((Object)(object)((MonoBehaviourPun)<ch>5__5).photonView != (Object)null)
									{
										((MonoBehaviourPun)<ch>5__5).photonView.RPC("WarpPlayerRPC", (RpcTarget)0, new object[2] { val, true });
									}
									((BaseUnityPlugin)plugin).Logger.LogInfo((object)$"[Checkpoint_Save] TeleportClientToHost: warped {((Object)<ch>5__5.player).name} to {val}");
								}
								catch (Exception ex)
								{
									((BaseUnityPlugin)plugin).Logger.LogWarning((object)("[Checkpoint_Save] TeleportClientToHost failed: " + ex));
									plugin.ShowMessage("Something went wrong while teleporting =(", Color.red, 8f);
								}
								<i>5__3++;
								if (<i>5__3 <= plugin.configRetryTeleportCount.Value)
								{
									goto IL_029e;
								}
							}
							else if (!(Mathf.Abs(<ch>5__5.Head.x - <hostPos>5__2.x) < plugin.configTeleportXOffset.Value) || !(Mathf.Abs(<ch>5__5.Head.z - <hostPos>5__2.z) < plugin.configTeleportZOffset.Value))
							{
								goto IL_029e;
							}
						}
						goto IL_0301;
						IL_0308:
						if (<>7__wrap3.MoveNext())
						{
							<ch>5__5 = <>7__wrap3.Current;
							if ((Object)(object)<ch>5__5 != (Object)(object)Character.localCharacter && (Object)(object)<ch>5__5 != (Object)null)
							{
								((MonoBehaviourPun)<ch>5__5).photonView.RPC("WarpPlayerRPC", (RpcTarget)0, new object[2] { <hostPos>5__2, true });
								<startTime>5__6 = Time.time;
								<i>5__3 = 0;
								goto IL_02e4;
							}
							goto IL_0301;
						}
						<>m__Finally1();
						<>7__wrap3 = default(List<Character>.Enumerator);
						return false;
						IL_02d1:
						if (<i>5__7 < plugin.configTeleportFramesToWait.Value)
						{
							<>2__current = null;
							<>1__state = 2;
							return true;
						}
						goto IL_02e4;
						IL_0301:
						<ch>5__5 = null;
						goto IL_0308;
						IL_029e:
						<i>5__7 = 0;
						goto IL_02d1;
					}
				}
				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;
				((IDisposable)<>7__wrap3).Dispose();
			}

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

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

			private object <>2__current;

			public Vector3 pos;

			public Plugin <>4__this;

			private float <startTimeLocal>5__2;

			private int <triedTeleportLocal>5__3;

			private int <i>5__4;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0049: Unknown result type (might be due to invalid IL or missing references)
				//IL_016c: Unknown result type (might be due to invalid IL or missing references)
				//IL_008d: Unknown result type (might be due to invalid IL or missing references)
				//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
				//IL_0131: Unknown result type (might be due to invalid IL or missing references)
				//IL_0102: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				Plugin plugin = <>4__this;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
					<i>5__4++;
					goto IL_0247;
				}
				<>1__state = -1;
				if ((Object)(object)Character.localCharacter == (Object)null)
				{
					return false;
				}
				((MonoBehaviourPun)Character.localCharacter).photonView.RPC("WarpPlayerRPC", (RpcTarget)0, new object[2] { pos, true });
				<startTimeLocal>5__2 = Time.time;
				<triedTeleportLocal>5__3 = 0;
				goto IL_025a;
				IL_0247:
				if (<i>5__4 < plugin.configTeleportFramesToWait.Value)
				{
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				goto IL_025a;
				IL_025a:
				if (Time.time - <startTimeLocal>5__2 < (float)plugin.configTeleportTryTime.Value)
				{
					if ((Object)(object)Character.localCharacter == (Object)null)
					{
						return false;
					}
					if (Mathf.Abs(Character.localCharacter.Head.y - pos.y) > plugin.configTeleportYOffset.Value)
					{
						try
						{
							Vector3 val = pos + new Vector3(0f, 0.5f, 0f);
							if ((Object)(object)((MonoBehaviourPun)Character.localCharacter).photonView != (Object)null)
							{
								((MonoBehaviourPun)Character.localCharacter).photonView.RPC("WarpPlayerRPC", (RpcTarget)0, new object[2] { val, true });
							}
							((BaseUnityPlugin)plugin).Logger.LogInfo((object)$"[Checkpoint_Save] TeleportClientToHost: warped {((Object)Character.localCharacter.player).name} to {val}");
						}
						catch (Exception ex)
						{
							((BaseUnityPlugin)plugin).Logger.LogWarning((object)("[Checkpoint_Save] TeleportClientToHost failed: " + ex));
							plugin.ShowMessage("Something went wrong while teleporting =(", Color.red, 8f);
						}
						<triedTeleportLocal>5__3++;
						if (<triedTeleportLocal>5__3 > plugin.configRetryTeleportCount.Value)
						{
							return false;
						}
					}
					else if (Mathf.Abs(Character.localCharacter.Head.x - pos.x) < plugin.configTeleportXOffset.Value && Mathf.Abs(Character.localCharacter.Head.z - pos.z) < plugin.configTeleportZOffset.Value)
					{
						if (!PhotonNetwork.OfflineMode)
						{
							((MonoBehaviour)plugin).StartCoroutine(plugin.TeleportClientToHost());
						}
						return false;
					}
					<i>5__4 = 0;
					goto IL_0247;
				}
				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 readonly int settingsVersion = 2;

		public ConfigEntry<KeyboardShortcut> configLoadKey;

		public ConfigEntry<bool> configAfflictions;

		public ConfigEntry<bool> configInventory;

		public ConfigEntry<bool> configOnetimeLoad;

		public ConfigEntry<int> configTeleportFramesToWait;

		public ConfigEntry<int> configRetryTeleportCount;

		public ConfigEntry<int> configTeleportTryTime;

		public ConfigEntry<float> configTeleportYOffset;

		public ConfigEntry<float> configTeleportXOffset;

		public ConfigEntry<float> configTeleportZOffset;

		public static Plugin Instance;

		private Harmony _harmony;

		private Player cachedPlayer;

		private AudioClip msgSound;

		private PhotonView pv;

		public string savedSegmentName;

		public List<ushort> backpackItemIds;

		private string msgText = "";

		private Color msgColor = Color.white;

		private float msgTime;

		private float msgDuration = 2f;

		private float msgAlpha;

		internal static float NoFallDamageUntil;

		internal static float RecentlyLoaded;

		internal static float RecentlyLitCampfire;

		private readonly HashSet<int> _readyActors = new HashSet<int>();

		private bool _localReadySent;

		private Vector2 msgPosition = new Vector2(0.5f, 0.1f);

		private static MethodInfo _playerAddItemMethod;

		public const string Id = "PEAK_Checkpoint_Save";

		internal static ManualLogSource Log { get; private set; }

		public static string Name => "PEAK_Checkpoint_Save";

		public static string Version => "0.2.6";

		internal static void ActivateFallDamageProtection(float seconds)
		{
			NoFallDamageUntil = Time.time + seconds;
		}

		private void Awake()
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			if (!Directory.Exists(Paths.PluginPath + "\\Checkpoint_Save"))
			{
				Directory.CreateDirectory(Paths.PluginPath + "\\Checkpoint_Save");
			}
			if (!Directory.Exists(Paths.PluginPath + "\\Checkpoint_Save\\Coop"))
			{
				Directory.CreateDirectory(Paths.PluginPath + "\\Checkpoint_Save\\Coop");
			}
			CheckConfigVersion();
			_harmony = new Harmony("peak.checkpoint.save.harmony");
			_harmony.PatchAll();
			Instance = this;
			pv = ((Component)this).gameObject.AddComponent<PhotonView>();
			pv.ViewID = 742;
			configLoadKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "loadKey", new KeyboardShortcut((KeyCode)287, Array.Empty<KeyCode>()), "Key for loading your save game (Default: F6)");
			configAfflictions = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "enableAfflictions", true, "Enable save/load of your current afflictions. (hunger, poison, cold, sleep...)");
			configInventory = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "enableInventory", true, "Enable save/load of your inventory items.");
			configOnetimeLoad = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "enableOnetimeLoad", false, "If enabled, you can only load once, until you reach the next checkpoint to save again. (Call it hardmode or so)");
			configTeleportFramesToWait = ((BaseUnityPlugin)this).Config.Bind<int>("Teleport (DO NOT CHANGE IF YOU DO NOT KNOW WHAT YOU DO!)", "teleportFramesToWait", 30, "Game frames to wait between teleport tries");
			configRetryTeleportCount = ((BaseUnityPlugin)this).Config.Bind<int>("Teleport (DO NOT CHANGE IF YOU DO NOT KNOW WHAT YOU DO!)", "retryTeleportCount", 30, "How often it will try to teleport the client to the save location");
			configTeleportTryTime = ((BaseUnityPlugin)this).Config.Bind<int>("Teleport (DO NOT CHANGE IF YOU DO NOT KNOW WHAT YOU DO!)", "timeToTryTeleportation", 30, "How long will it try to teleport (in seconds)");
			configTeleportYOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Teleport (DO NOT CHANGE IF YOU DO NOT KNOW WHAT YOU DO!)", "teleportYOffset", 2f, "the Y offset for teleportation check");
			configTeleportXOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Teleport (DO NOT CHANGE IF YOU DO NOT KNOW WHAT YOU DO!)", "teleportXOffset", 6f, "the X offset for teleportation check");
			configTeleportZOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Teleport (DO NOT CHANGE IF YOU DO NOT KNOW WHAT YOU DO!)", "teleportZOffset", 6f, "the Z offset for teleportation check");
		}

		private void Update()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value = configLoadKey.Value;
			if (((KeyboardShortcut)(ref value)).IsDown())
			{
				if (PhotonNetwork.OfflineMode)
				{
					LoadPlayerOffline();
				}
				else
				{
					LoadPlayerCoop();
				}
			}
			else
			{
				Input.GetKey((KeyCode)282);
			}
		}

		public void OnGUI()
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Expected O, but got Unknown
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			if (msgTime > 0f)
			{
				float num = msgTime / msgDuration;
				if (num > 0.9f)
				{
					msgAlpha = Mathf.Lerp(msgAlpha, 1f, 6f * Time.deltaTime);
				}
				else if (num < 0.1f)
				{
					msgAlpha = Mathf.Lerp(msgAlpha, 0f, 3f * Time.deltaTime);
				}
				else
				{
					msgAlpha = 1f;
				}
				GUIStyle val = new GUIStyle(GUI.skin.label)
				{
					fontSize = 32,
					alignment = (TextAnchor)1
				};
				GUIStyle val2 = new GUIStyle(val);
				val2.normal.textColor = new Color(0f, 0f, 0f, msgAlpha * 0.7f);
				val.normal.textColor = new Color(msgColor.r, msgColor.g, msgColor.b, msgAlpha);
				float num2 = (float)Screen.width * msgPosition.x;
				float num3 = (float)Screen.height * msgPosition.y;
				Rect val3 = default(Rect);
				((Rect)(ref val3))..ctor(num2 - 300f, num3, 600f, 100f);
				GUI.Label(new Rect(((Rect)(ref val3)).x + 2f, ((Rect)(ref val3)).y + 2f, ((Rect)(ref val3)).width, ((Rect)(ref val3)).height), msgText, val2);
				GUI.Label(val3, msgText, val);
				msgTime -= Time.deltaTime;
			}
		}

		private bool AllPlayersReady()
		{
			if (PhotonNetwork.OfflineMode)
			{
				return true;
			}
			if (!PhotonNetwork.IsMasterClient)
			{
				return false;
			}
			Player[] playerList = PhotonNetwork.PlayerList;
			if (playerList == null || playerList.Length == 0)
			{
				return false;
			}
			Player[] array = playerList;
			foreach (Player val in array)
			{
				if (!val.IsInactive && !_readyActors.Contains(val.ActorNumber))
				{
					return false;
				}
			}
			return true;
		}

		public void CheckConfigVersion()
		{
			if (File.Exists(Paths.PluginPath + "\\Checkpoint_Save\\settingsVersion"))
			{
				int num = Convert.ToInt32(File.ReadAllText(Paths.PluginPath + "\\Checkpoint_Save\\settingsVersion"));
				if (num >= settingsVersion)
				{
					return;
				}
				try
				{
					File.Delete(Path.Combine(Paths.PluginPath + "\\Checkpoint_Save\\peak_save_offline.json"));
				}
				catch
				{
				}
				try
				{
					string[] files = Directory.GetFiles(Path.Combine(Paths.PluginPath + "\\Checkpoint_Save\\Coop"));
					string[] array = files;
					foreach (string path in array)
					{
						File.Delete(path);
					}
					return;
				}
				catch
				{
					return;
				}
			}
			File.WriteAllText(Paths.PluginPath + "\\Checkpoint_Save\\settingsVersion", settingsVersion.ToString());
			try
			{
				File.Delete(Path.Combine(Paths.PluginPath + "\\Checkpoint_Save\\peak_save_offline.json"));
			}
			catch
			{
			}
			try
			{
				string[] files2 = Directory.GetFiles(Path.Combine(Paths.PluginPath + "\\Checkpoint_Save\\Coop"));
				string[] array2 = files2;
				foreach (string path2 in array2)
				{
					File.Delete(path2);
				}
			}
			catch
			{
			}
		}

		public void ShowMessage(string text, Color color, float duration = 2.5f, AudioClip sound = null)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			msgText = text;
			msgColor = color;
			msgDuration = duration;
			msgTime = duration;
			msgAlpha = 0f;
			msgSound = sound;
			if ((Object)(object)sound != (Object)null)
			{
				AudioSource.PlayClipAtPoint(sound, ((Component)Camera.main).transform.position);
			}
		}

		private MapHandler GetMapHandler()
		{
			return Object.FindFirstObjectByType<MapHandler>();
		}

		private Player GetLocalPlayer()
		{
			if ((Object)(object)cachedPlayer != (Object)null)
			{
				return cachedPlayer;
			}
			Player[] array = Object.FindObjectsByType<Player>((FindObjectsSortMode)0);
			Player[] array2 = array;
			foreach (Player val in array2)
			{
				PhotonView component = ((Component)val).GetComponent<PhotonView>();
				if ((Object)(object)component != (Object)null && component.IsMine)
				{
					cachedPlayer = val;
					((BaseUnityPlugin)this).Logger.LogInfo((object)"[Checkpoint_Save] Local Player via PhotonView.IsMine found.");
					return cachedPlayer;
				}
			}
			if (array.Length != 0)
			{
				cachedPlayer = array[0];
				((BaseUnityPlugin)this).Logger.LogWarning((object)"[Checkpoint_Save] Local Player randomised (used first Player).");
			}
			return cachedPlayer;
		}

		private string GetPlayerSaveFile(string userId)
		{
			try
			{
				if (PhotonNetwork.OfflineMode)
				{
					return Path.Combine(Paths.PluginPath + "\\Checkpoint_Save\\peak_save_offline.json");
				}
				return Path.Combine(Paths.PluginPath + "\\Checkpoint_Save\\Coop\\peak_save_" + userId + ".json");
			}
			catch
			{
				return null;
			}
		}

		[IteratorStateMachine(typeof(<JumpToMapSegment>d__46))]
		private IEnumerator JumpToMapSegment(SaveData data)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <JumpToMapSegment>d__46(0)
			{
				<>4__this = this,
				data = data
			};
		}

		[IteratorStateMachine(typeof(<TeleportToPosition>d__47))]
		private IEnumerator TeleportToPosition(Vector3 pos)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <TeleportToPosition>d__47(0)
			{
				<>4__this = this,
				pos = pos
			};
		}

		[IteratorStateMachine(typeof(<TeleportClientToHost>d__48))]
		private IEnumerator TeleportClientToHost()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <TeleportClientToHost>d__48(0)
			{
				<>4__this = this
			};
		}

		[IteratorStateMachine(typeof(<LoadInventoryDelayed>d__49))]
		private IEnumerator LoadInventoryDelayed()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <LoadInventoryDelayed>d__49(0)
			{
				<>4__this = this
			};
		}

		private void LoadPlayerInventory(SaveData data, Player player, Character ch)
		{
			if ((Object)(object)player == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"[Checkpoint_Save] LoadPlayerInventory: no player.");
				return;
			}
			if (player.itemSlots != null)
			{
				ItemSlot[] itemSlots = player.itemSlots;
				foreach (ItemSlot val in itemSlots)
				{
					if (val != null)
					{
						try
						{
							val.EmptyOut();
						}
						catch
						{
						}
					}
				}
			}
			try
			{
				((ItemSlot)player.backpackSlot).EmptyOut();
			}
			catch
			{
			}
			if (data.inventoryItemIds == null || data.inventoryItemIds.Count == 0)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"[Checkpoint_Save] LoadPlayerInventory: no inventoryPrefabs in save.");
				return;
			}
			if ((Object)(object)ch == (Object)null || (Object)(object)((MonoBehaviourPun)ch).photonView == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"[Checkpoint_Save] LoadPlayerInventory: missing Character or photonView.");
				return;
			}
			if (data.hasBackpack)
			{
				try
				{
					AddItemToInventory(player, 6);
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("[Checkpoint_Save] SpawnBackpackItemsFromSave: instantiate failed for 'Backpack': " + ex));
				}
			}
			int num = 0;
			foreach (ushort inventoryItemId in data.inventoryItemIds)
			{
				if (inventoryItemId != 0 && AddItemToInventory(player, inventoryItemId))
				{
					num++;
				}
			}
		}

		private void LoadBackpackFromSave(Player player, SaveData data)
		{
			if (data.backpackItemIds == null || data.backpackItemIds.Count == 0)
			{
				return;
			}
			BackpackData backpackData = GetBackpackData(player);
			if (backpackData == null || backpackData.itemSlots == null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"[Checkpoint_Save] LoadBackpackFromSave: no BackpackData or itemSlots.");
				return;
			}
			for (int i = 0; i < backpackData.itemSlots.Length; i++)
			{
				if (backpackData.itemSlots[i] != null)
				{
					backpackData.itemSlots[i].EmptyOut();
				}
			}
			int num = Math.Min(data.backpackItemIds.Count, backpackData.itemSlots.Length);
			for (byte b = 0; b < num; b++)
			{
				AddItemToBackpack(backpackData, data.backpackItemIds[b], b);
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"[Checkpoint_Save] Backpack loaded, items={num}");
		}

		private BackpackData GetBackpackData(Player p)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)p == (Object)null || p.backpackSlot == null || !p.backpackSlot.hasBackpack)
			{
				return null;
			}
			ItemSlot backpackSlot = (ItemSlot)(object)p.backpackSlot;
			if (backpackSlot.data == null)
			{
				return null;
			}
			BackpackData val = null;
			DataEntryKey val2 = (DataEntryKey)7;
			if (!backpackSlot.data.TryGetDataEntry<BackpackData>(val2, ref val) || val == null)
			{
				backpackSlot.data.RegisterNewEntry<BackpackData>(val2);
				backpackSlot.data.TryGetDataEntry<BackpackData>(val2, ref val);
			}
			return val;
		}

		private bool AddItemToBackpack(BackpackData backpackdata, ushort itemId, byte slot)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			try
			{
				if (backpackdata == null || backpackdata.itemSlots == null)
				{
					return false;
				}
				if (slot >= backpackdata.itemSlots.Length)
				{
					return false;
				}
				ItemSlot val = backpackdata.itemSlots[slot];
				if (val == null)
				{
					return false;
				}
				if (!val.IsEmpty())
				{
					return false;
				}
				Item val2 = null;
				if (!ItemDatabase.TryGetItem(itemId, ref val2) || (Object)(object)val2 == (Object)null)
				{
					return false;
				}
				ItemInstanceData val3 = new ItemInstanceData(Guid.NewGuid());
				ItemInstanceDataHandler.AddInstanceData(val3);
				backpackdata.AddItem(val2, val3, slot);
				return true;
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("[Checkpoint_Save] AddItemToBackpack error: " + ex));
				return false;
			}
		}

		private bool AddItemToInventory(Player player, ushort itemId)
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			try
			{
				if (_playerAddItemMethod == null)
				{
					_playerAddItemMethod = typeof(Player).GetMethod("AddItem", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[3]
					{
						typeof(ushort),
						typeof(ItemInstanceData),
						typeof(ItemSlot).MakeByRefType()
					}, null);
					if (_playerAddItemMethod == null)
					{
						((BaseUnityPlugin)this).Logger.LogError((object)"[Checkpoint_Save] AddItemToInventory: Player.AddItem(...) method not found.");
						return false;
					}
				}
				ItemInstanceData val = new ItemInstanceData(Guid.NewGuid());
				ItemInstanceDataHandler.AddInstanceData(val);
				ItemSlot val2 = null;
				object[] parameters = new object[3] { itemId, val, val2 };
				_playerAddItemMethod.Invoke(player, parameters);
				return true;
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("[Checkpoint_Save] AddItemToInventory error: " + ex));
				return false;
			}
		}

		private Item ResolveItemByName(string prefabName)
		{
			if (string.IsNullOrEmpty(prefabName))
			{
				return null;
			}
			Item[] array = Resources.FindObjectsOfTypeAll<Item>();
			Item[] array2 = array;
			foreach (Item val in array2)
			{
				if ((Object)(object)val != (Object)null && ((Object)val).name == prefabName)
				{
					return val;
				}
			}
			((BaseUnityPlugin)this).Logger.LogWarning((object)("[Checkpoint_Save] ResolveItemByName: prefab not found: " + prefabName));
			return null;
		}

		public void SavePlayerOffline()
		{
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Expected O, but got I4
			//IL_01fd: Expected O, but got I4
			//IL_0209: Expected O, but got I4
			//IL_021b: Expected O, but got I4
			//IL_021d: Expected O, but got I4
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4->IL01d4: Incompatible stack types: O vs I4
			//IL_01cd->IL01d4: Incompatible stack types: I4 vs O
			//IL_01cd->IL01d4: Incompatible stack types: O vs I4
			try
			{
				Player localPlayer = GetLocalPlayer();
				if ((Object)(object)localPlayer == (Object)null)
				{
					ShowMessage("No Player found – cannot save progress!", Color.red, 8f);
					((BaseUnityPlugin)this).Logger.LogError((object)"[Checkpoint_Save] no Player found – cannot save progress.");
					return;
				}
				string playerSaveFile = GetPlayerSaveFile(NetworkingUtilities.UserId(localPlayer));
				Character localCharacter = Character.localCharacter;
				Vector3 val;
				if ((Object)(object)localCharacter != (Object)null)
				{
					val = localCharacter.Head;
				}
				else
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)"[Checkpoint_Save] Character.localCharacter is null – used player.transform as fallback.");
					val = ((Component)localPlayer).transform.position;
				}
				Scene activeScene = SceneManager.GetActiveScene();
				string name = ((Scene)(ref activeScene)).name;
				List<ushort> list = new List<ushort>();
				if (localPlayer.itemSlots != null)
				{
					ItemSlot[] itemSlots = localPlayer.itemSlots;
					foreach (ItemSlot val2 in itemSlots)
					{
						if (val2 != null && !val2.IsEmpty() && !((Object)(object)val2.prefab == (Object)null))
						{
							try
							{
								list.Add(val2.prefab.itemID);
							}
							catch
							{
							}
						}
					}
				}
				backpackItemIds = new List<ushort>();
				BackpackData backpackData = GetBackpackData(localPlayer);
				try
				{
					if (backpackData != null)
					{
						ItemSlot[] itemSlots2 = backpackData.itemSlots;
						foreach (ItemSlot val3 in itemSlots2)
						{
							if (val3 != null && !val3.IsEmpty() && !((Object)(object)val3.prefab == (Object)null))
							{
								ushort itemID = val3.prefab.itemID;
								backpackItemIds.Add(itemID);
							}
						}
					}
				}
				catch
				{
				}
				CharacterAfflictions afflictions = Character.localCharacter.refs.afflictions;
				MapHandler mapHandler = GetMapHandler();
				object obj3 = new SaveData
				{
					settingsVersion = settingsVersion,
					posX = val.x,
					posY = val.y,
					posZ = val.z,
					sceneName = name
				};
				object obj4 = obj3;
				int num;
				if ((Object)(object)mapHandler != (Object)null)
				{
					obj3 = mapHandler.GetCurrentSegment();
					num = (int)obj3;
				}
				else
				{
					num = 0;
					obj3 = num;
					num = (int)obj3;
				}
				((SaveData)obj4).segment = (Segment)obj3;
				((SaveData)num).hasBackpack = localPlayer.backpackSlot != null && localPlayer.backpackSlot.hasBackpack;
				((SaveData)num).inventoryItemIds = list;
				((SaveData)num).backpackItemIds = backpackItemIds;
				((SaveData)num).afflictions_current = afflictions.currentStatuses.ToArray();
				SaveData saveData = (SaveData)num;
				File.WriteAllText(playerSaveFile, JsonConvert.SerializeObject((object)saveData, (Formatting)1));
				ShowMessage("Saved game progress", Color.green, 8f);
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"[Checkpoint_Save] Position + inventory saved. Pos: {val} Scene: {name}, Items: {list.Count}");
			}
			catch (Exception ex)
			{
				ShowMessage("Something went wrong while saving progress =(", Color.red, 8f);
				((BaseUnityPlugin)this).Logger.LogError((object)("[Checkpoint_Save] Error while saving progress: " + ex));
			}
		}

		public void SavePlayerCoop()
		{
			//IL_0373: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Expected O, but got I4
			//IL_02b7: Expected O, but got I4
			//IL_02c3: Expected O, but got I4
			//IL_02d5: Expected O, but got I4
			//IL_02d7: Expected O, but got I4
			//IL_02ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_031d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c->IL028c: Incompatible stack types: O vs I4
			//IL_0285->IL028c: Incompatible stack types: I4 vs O
			//IL_0285->IL028c: Incompatible stack types: O vs I4
			try
			{
				try
				{
					if (PhotonNetwork.IsMasterClient)
					{
						string[] files = Directory.GetFiles(Path.Combine(Paths.PluginPath + "\\Checkpoint_Save\\Coop"));
						string[] array = files;
						foreach (string path in array)
						{
							File.Delete(path);
						}
					}
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("[Checkpoint_Save] Error while deleting save files: " + ex));
				}
				Player[] array2 = Object.FindObjectsOfType<Player>();
				foreach (Player val in array2)
				{
					foreach (Character allCharacter in Character.AllCharacters)
					{
						if (!(NetworkingUtilities.UserId(allCharacter.player) == NetworkingUtilities.UserId(val)))
						{
							continue;
						}
						if ((Object)(object)val == (Object)null)
						{
							ShowMessage("No Player found – cannot save progress!", Color.red, 8f);
							((BaseUnityPlugin)this).Logger.LogError((object)"[Checkpoint_Save] no Player found – cannot save progress.");
							return;
						}
						string playerSaveFile = GetPlayerSaveFile(NetworkingUtilities.UserId(val));
						Vector3 val2;
						if ((Object)(object)allCharacter != (Object)null)
						{
							val2 = allCharacter.Head;
						}
						else
						{
							((BaseUnityPlugin)this).Logger.LogWarning((object)"[Checkpoint_Save] Character.localCharacter is null – used player.transform as fallback.");
							val2 = ((Component)val).transform.position;
						}
						Scene activeScene = SceneManager.GetActiveScene();
						string name = ((Scene)(ref activeScene)).name;
						List<ushort> list = new List<ushort>();
						if (val.itemSlots != null)
						{
							ItemSlot[] itemSlots = val.itemSlots;
							foreach (ItemSlot val3 in itemSlots)
							{
								if (val3 != null && !val3.IsEmpty() && !((Object)(object)val3.prefab == (Object)null))
								{
									try
									{
										list.Add(val3.prefab.itemID);
									}
									catch
									{
									}
								}
							}
						}
						backpackItemIds = new List<ushort>();
						BackpackData backpackData = GetBackpackData(val);
						try
						{
							if (backpackData != null)
							{
								ItemSlot[] itemSlots2 = backpackData.itemSlots;
								foreach (ItemSlot val4 in itemSlots2)
								{
									if (val4 != null && !val4.IsEmpty() && !((Object)(object)val4.prefab == (Object)null))
									{
										ushort itemID = val4.prefab.itemID;
										backpackItemIds.Add(itemID);
									}
								}
							}
						}
						catch
						{
						}
						CharacterAfflictions afflictions = allCharacter.refs.afflictions;
						MapHandler mapHandler = GetMapHandler();
						object obj3 = new SaveData
						{
							settingsVersion = settingsVersion,
							posX = val2.x,
							posY = val2.y,
							posZ = val2.z,
							sceneName = name
						};
						object obj4 = obj3;
						int num;
						if ((Object)(object)mapHandler != (Object)null)
						{
							obj3 = mapHandler.GetCurrentSegment();
							num = (int)obj3;
						}
						else
						{
							num = 0;
							obj3 = num;
							num = (int)obj3;
						}
						((SaveData)obj4).segment = (Segment)obj3;
						((SaveData)num).hasBackpack = val.backpackSlot != null && val.backpackSlot.hasBackpack;
						((SaveData)num).inventoryItemIds = list;
						((SaveData)num).backpackItemIds = backpackItemIds;
						((SaveData)num).afflictions_current = afflictions.currentStatuses.ToArray();
						SaveData saveData = (SaveData)num;
						File.WriteAllText(playerSaveFile, JsonConvert.SerializeObject((object)saveData, (Formatting)1));
						ShowMessage("Saved game progress", Color.green, 8f);
						pv.RPC("RPC_SendSaveMessage", (RpcTarget)1, Array.Empty<object>());
						((BaseUnityPlugin)this).Logger.LogInfo((object)$"[Checkpoint_Save] Position + inventory saved. Pos: {val2} Scene: {name}, Items: {list.Count}");
					}
				}
			}
			catch (Exception ex2)
			{
				ShowMessage("Something went wrong while saving progress =(", Color.red, 8f);
				((BaseUnityPlugin)this).Logger.LogError((object)("[Checkpoint_Save] Error while saving progress: " + ex2));
			}
		}

		public void LoadPlayerOffline()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: 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)
			try
			{
				Scene activeScene = SceneManager.GetActiveScene();
				if (((Scene)(ref activeScene)).name == "Airport")
				{
					ShowMessage("Please load into a level first.", Color.yellow, 8f);
					((BaseUnityPlugin)this).Logger.LogError((object)"[Checkpoint_Save] Tried to load save at Airport!");
					return;
				}
				if (!PhotonNetwork.IsMasterClient)
				{
					ShowMessage("Only the host can load the save!", Color.red, 8f);
					((BaseUnityPlugin)this).Logger.LogError((object)"[Checkpoint_Save] Tried to load as client!");
					return;
				}
				if (RecentlyLoaded > Time.time)
				{
					string arg = ((RecentlyLoaded - Time.time > 1f) ? "seconds" : "second");
					ShowMessage($"Please wait {Convert.ToInt32(RecentlyLoaded - Time.time)} {arg} before loading again.", Color.yellow, 8f);
					return;
				}
				string playerSaveFile = GetPlayerSaveFile("");
				if (!File.Exists(playerSaveFile))
				{
					ShowMessage("No save file found!", Color.red, 8f);
					((BaseUnityPlugin)this).Logger.LogWarning((object)"[Checkpoint_Save] No save file found.");
					return;
				}
				Player localPlayer = GetLocalPlayer();
				string text = File.ReadAllText(playerSaveFile);
				SaveData data = JsonConvert.DeserializeObject<SaveData>(text);
				((MonoBehaviour)this).StartCoroutine(JumpToMapSegment(data));
				((MonoBehaviour)this).StartCoroutine(LoadInventoryDelayed());
				if (configOnetimeLoad.Value)
				{
					try
					{
						File.Delete(Path.Combine(Paths.PluginPath + "\\Checkpoint_Save\\peak_save_offline.json"));
					}
					catch (Exception ex)
					{
						((BaseUnityPlugin)this).Logger.LogError((object)("[Checkpoint_Save] Error while deleting save files: " + ex));
					}
				}
				ShowMessage("Save game loaded!", Color.cyan, 8f);
				RecentlyLoaded = Time.time + 15f;
				RecentlyLitCampfire = Time.time - 1f;
			}
			catch (Exception ex2)
			{
				ShowMessage("Error while loading save file!", Color.red, 8f);
				((BaseUnityPlugin)this).Logger.LogError((object)("[Checkpoint_Save] Error while loading save file: " + ex2));
				RecentlyLoaded = Time.time - 1f;
			}
		}

		public void LoadPlayerCoop()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: 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)
			try
			{
				Scene activeScene = SceneManager.GetActiveScene();
				if (((Scene)(ref activeScene)).name == "Airport")
				{
					ShowMessage("Please load into a level first.", Color.yellow, 8f);
					((BaseUnityPlugin)this).Logger.LogError((object)"[Checkpoint_Save] Tried to load save at Airport!");
					return;
				}
				if (!PhotonNetwork.IsMasterClient)
				{
					ShowMessage("Only the host can load the save!", Color.red, 8f);
					((BaseUnityPlugin)this).Logger.LogError((object)"[Checkpoint_Save] Tried to load as client!");
					return;
				}
				if (RecentlyLoaded > Time.time)
				{
					string arg = ((RecentlyLoaded - Time.time > 1f) ? "seconds" : "second");
					ShowMessage($"Please wait {Convert.ToInt32(RecentlyLoaded - Time.time)} {arg} before loading again.", Color.yellow, 8f);
					return;
				}
				Player localPlayer = GetLocalPlayer();
				string playerSaveFile = GetPlayerSaveFile(NetworkingUtilities.UserId(localPlayer));
				if (!File.Exists(playerSaveFile))
				{
					ShowMessage("No save file found!", Color.red, 8f);
					((BaseUnityPlugin)this).Logger.LogWarning((object)"[Checkpoint_Save] No save file found.");
					return;
				}
				string text = File.ReadAllText(playerSaveFile);
				SaveData data = JsonConvert.DeserializeObject<SaveData>(text);
				((MonoBehaviour)this).StartCoroutine(JumpToMapSegment(data));
				((MonoBehaviour)this).StartCoroutine(LoadInventoryDelayed());
				if (configOnetimeLoad.Value)
				{
					try
					{
						if (PhotonNetwork.IsMasterClient)
						{
							string[] files = Directory.GetFiles(Path.Combine(Paths.PluginPath + "\\Checkpoint_Save\\Coop"));
							string[] array = files;
							foreach (string path in array)
							{
								File.Delete(path);
							}
						}
					}
					catch (Exception ex)
					{
						((BaseUnityPlugin)this).Logger.LogError((object)("[Checkpoint_Save] Error while deleting save files: " + ex));
					}
				}
				ShowMessage("Save game loaded!", Color.cyan, 8f);
				pv.RPC("RPC_SendLoadMessage", (RpcTarget)1, Array.Empty<object>());
				RecentlyLoaded = Time.time + 15f;
				RecentlyLitCampfire = Time.time - 1f;
			}
			catch (Exception ex2)
			{
				ShowMessage("Error while loading save file!", Color.red, 8f);
				((BaseUnityPlugin)this).Logger.LogError((object)("[Checkpoint_Save] Error while loading save file: " + ex2));
				RecentlyLoaded = Time.time - 1f;
			}
		}

		[PunRPC]
		public void RPC_RequestSave()
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[Checkpoint_Save] RPC: Save requested.");
			if (PhotonNetwork.IsMasterClient)
			{
				SavePlayerCoop();
				RecentlyLitCampfire = Time.time + 60f;
			}
		}

		[PunRPC]
		public void RPC_RecentlyLitCampfire()
		{
			if (!PhotonNetwork.IsMasterClient)
			{
				RecentlyLitCampfire = Time.time + 60f;
			}
		}

		[PunRPC]
		public void RPC_RequestFalldamageProtection()
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[Checkpoint_Save] RPC: Falldamage protection requested.");
			ActivateFallDamageProtection(20f);
		}

		[PunRPC]
		public void RPC_SendLoadMessage()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			ShowMessage("Save game loaded!", Color.cyan, 8f);
		}

		[PunRPC]
		public void RPC_SendSaveMessage()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			ShowMessage("Saved game progress", Color.green, 8f);
		}

		[PunRPC]
		public void RPC_ApplyBackpackFromSave(string userId, int[] itemIds)
		{
			try
			{
				Player localPlayer = GetLocalPlayer();
				if ((Object)(object)localPlayer == (Object)null)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)"[Checkpoint_Save] RPC_ApplyBackpackFromSave: no local player.");
				}
				else
				{
					if (NetworkingUtilities.UserId(localPlayer) != userId)
					{
						return;
					}
					if (itemIds == null || itemIds.Length == 0)
					{
						((BaseUnityPlugin)this).Logger.LogInfo((object)"[Checkpoint_Save] RPC_ApplyBackpackFromSave: no items for this player.");
						return;
					}
					BackpackData backpackData = GetBackpackData(localPlayer);
					if (backpackData == null || backpackData.itemSlots == null)
					{
						((BaseUnityPlugin)this).Logger.LogWarning((object)"[Checkpoint_Save] RPC_ApplyBackpackFromSave: no BackpackData or itemSlots for local player.");
						return;
					}
					for (int i = 0; i < backpackData.itemSlots.Length; i++)
					{
						if (backpackData.itemSlots[i] != null)
						{
							backpackData.itemSlots[i].EmptyOut();
						}
					}
					int num = Math.Min(itemIds.Length, backpackData.itemSlots.Length);
					for (byte b = 0; b < num; b++)
					{
						ushort num2 = (ushort)itemIds[b];
						if (num2 != 0)
						{
							AddItemToBackpack(backpackData, num2, b);
						}
					}
					((BaseUnityPlugin)this).Logger.LogInfo((object)$"[Checkpoint_Save] RPC_ApplyBackpackFromSave: applied {num} items for local player.");
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("[Checkpoint_Save] RPC_ApplyBackpackFromSave error: " + ex));
			}
		}

		[PunRPC]
		public void RPC_ApplyAfflictions(string userId, float[] statuses)
		{
			try
			{
				Player localPlayer = GetLocalPlayer();
				if ((Object)(object)localPlayer == (Object)null)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)"[Checkpoint_Save] RPC_ApplyAfflictions: no local player.");
				}
				else
				{
					if (NetworkingUtilities.UserId(localPlayer) != userId)
					{
						return;
					}
					Character localCharacter = Character.localCharacter;
					if ((Object)(object)localCharacter == (Object)null)
					{
						((BaseUnityPlugin)this).Logger.LogWarning((object)"[Checkpoint_Save] RPC_ApplyAfflictions: no local Character.");
						return;
					}
					CharacterAfflictions afflictions = localCharacter.refs.afflictions;
					if (statuses != null && afflictions.currentStatuses != null && afflictions.currentStatuses.Length == statuses.Length)
					{
						Array.Copy(statuses, afflictions.currentStatuses, afflictions.currentStatuses.Length);
					}
					else
					{
						((BaseUnityPlugin)this).Logger.LogWarning((object)"[Checkpoint_Save] RPC_ApplyAfflictions: length mismatch or null.");
					}
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("[Checkpoint_Save] RPC_ApplyAfflictions error: " + ex));
			}
		}

		[PunRPC]
		public void RPC_ClientReady(int actorNumber)
		{
			if (PhotonNetwork.IsMasterClient && !_readyActors.Contains(actorNumber))
			{
				_readyActors.Add(actorNumber);
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"[Checkpoint_Save] Player {actorNumber} reported READY. ReadyCount={_readyActors.Count}/{PhotonNetwork.PlayerList.Length}");
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}