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)
{
}
}
}