Decompiled source of No Save Delete v1.3.1

Plugins/NoSaveDelete.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Photon.Pun;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("NoSaveDeleteMod")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("NoSaveDeleteMod")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("194122da-d5ca-4c8a-b922-4931bcfb19f6")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
[HarmonyPatch(typeof(PlayerAvatar), "PlayerDeathRPC")]
public class AutoLoadMultiplayer
{
	private static async void Postfix()
	{
		if (!SemiFunc.IsMultiplayer())
		{
			return;
		}
		if (!MyModConfig.AutoLoadInMultiplayer.Value)
		{
			Debug.Log((object)"[NoSaveDelete] Auto-load disabled due to AutoLoadInMultiplayer being enabled.");
		}
		else
		{
			if (!PhotonNetwork.IsMasterClient)
			{
				return;
			}
			FieldInfo deadSetField = AccessTools.Field(typeof(PlayerAvatar), "deadSet");
			List<PlayerAvatar> players = SemiFunc.PlayerGetList();
			bool allDead = true;
			foreach (PlayerAvatar player in players)
			{
				if (!(bool)deadSetField.GetValue(player))
				{
					Debug.Log((object)"[NoSaveDelete] Not all players are dead. Reload is not performed.");
					allDead = false;
					break;
				}
			}
			if (allDead)
			{
				PreventSaveGameUltimate.SetAllPlayersDead();
				FieldInfo saveFileField = AccessTools.Field(typeof(StatsManager), "saveFileCurrent");
				string saveFileName = (string)saveFileField.GetValue(StatsManager.instance);
				if (string.IsNullOrEmpty(saveFileName))
				{
					Debug.LogWarning((object)"[NoSaveDelete] No save file to load!");
					PreventSaveGameUltimate.ResetAllPlayersDead();
				}
				else if ((Object)(object)RunManager.instance.levelCurrent == (Object)(object)RunManager.instance.levelShop)
				{
					Debug.Log((object)"[NoSaveDelete] All players died in the SHOP. Restarting save WITHOUT restoring backup...");
					await Task.Delay(650);
					SemiFunc.MenuActionSingleplayerGame(saveFileName, (List<string>)null);
					PreventSaveGameUltimate.ResetAllPlayersDead();
				}
				else
				{
					Debug.Log((object)"[NoSaveDelete] All players died. Restoring backup...");
					RestoreBackup(saveFileName);
					await Task.Delay(650);
					SemiFunc.MenuActionSingleplayerGame(saveFileName, (List<string>)null);
					await Task.Delay(1500);
					ReloadSaveInMemory(saveFileName);
					PreventSaveGameUltimate.ResetAllPlayersDead();
				}
			}
		}
	}

	private static void ReloadSaveInMemory(string saveFileName)
	{
		try
		{
			MethodInfo method = typeof(StatsManager).GetMethod("LoadGame", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (method != null)
			{
				method.Invoke(StatsManager.instance, new object[2] { saveFileName, null });
				Debug.Log((object)("[NoSaveDelete] Save data reloaded in memory for " + saveFileName));
			}
			else
			{
				Debug.LogWarning((object)"[NoSaveDelete] Unable to find LoadGame method for memory reload!");
			}
		}
		catch (Exception ex)
		{
			Debug.LogError((object)("[NoSaveDelete] Error reloading save in memory: " + ex.Message));
		}
	}

	private static void RestoreBackup(string saveFileName)
	{
		string text = Path.Combine(Application.persistentDataPath, "saves", saveFileName);
		if (!Directory.Exists(text))
		{
			Debug.LogError((object)("[NoSaveDelete] Save folder not found: " + text));
			return;
		}
		string text2 = FindLatestBackup(text, saveFileName);
		if (!string.IsNullOrEmpty(text2))
		{
			try
			{
				string text3 = Path.Combine(text, saveFileName + ".es3");
				if (File.Exists(text3))
				{
					File.Delete(text3);
				}
				File.Copy(text2, text3);
				Debug.Log((object)("[NoSaveDelete] Backup restored from: " + text2));
				MethodInfo method = typeof(StatsManager).GetMethod("LoadGame", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (method != null)
				{
					method.Invoke(StatsManager.instance, new object[2] { saveFileName, null });
					Debug.Log((object)("[NoSaveDelete] Save data reloaded in memory for " + saveFileName));
				}
				else
				{
					Debug.LogWarning((object)"[NoSaveDelete] Unable to find LoadGame method for memory reload!");
				}
				return;
			}
			catch (IOException ex)
			{
				Debug.LogError((object)("[NoSaveDelete] Restore error: " + ex.Message));
				return;
			}
		}
		Debug.LogWarning((object)"[NoSaveDelete] No valid backup found!");
	}

	private static string FindLatestBackup(string directory, string saveFileName)
	{
		if (!Directory.Exists(directory))
		{
			return null;
		}
		string[] files = Directory.GetFiles(directory, saveFileName + "_BACKUP*.es3");
		if (files.Length == 0)
		{
			return null;
		}
		Regex regex = new Regex("_BACKUP(\\d+)", RegexOptions.IgnoreCase);
		return (from file in files
			select new
			{
				FilePath = file,
				BackupNumber = ExtractBackupNumber(file, regex)
			} into b
			where b.BackupNumber >= 0
			orderby b.BackupNumber descending
			select b).FirstOrDefault()?.FilePath;
	}

	private static int ExtractBackupNumber(string filePath, Regex regex)
	{
		string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filePath);
		Match match = regex.Match(fileNameWithoutExtension);
		if (match.Success && int.TryParse(match.Groups[1].Value, out var result))
		{
			return result;
		}
		return -1;
	}
}
[HarmonyPatch(typeof(GameDirector), "Update")]
public class CheckArenaAndRestoreBackup
{
	private static bool shouldRestoreBackup;

	private static bool hasLoggedArena;

	private static void Postfix(GameDirector __instance)
	{
		if (!MyModConfig.AutoLoadInMultiplayer.Value && SemiFunc.IsMultiplayer() && PhotonNetwork.IsMasterClient)
		{
			bool flag = (Object)(object)RunManager.instance.levelCurrent == (Object)(object)RunManager.instance.levelArena;
			bool flag2 = (Object)(object)RunManager.instance.levelCurrent == (Object)(object)RunManager.instance.levelLobbyMenu;
			if (flag && !hasLoggedArena)
			{
				hasLoggedArena = true;
				shouldRestoreBackup = true;
				Debug.Log((object)"[NoSaveDelete] The game is on the arena. Enabling backup restoration after returning to the lobby.");
			}
			if (shouldRestoreBackup && flag2)
			{
				shouldRestoreBackup = false;
				hasLoggedArena = false;
				DelayedRestoreBackup();
			}
		}
	}

	private static async Task DelayedRestoreBackup()
	{
		Debug.Log((object)"[NoSaveDelete] Waiting 3 seconds before restoring the backup...");
		await Task.Delay(3000);
		RestoreBackup();
	}

	private static void RestoreBackup()
	{
		FieldInfo fieldInfo = AccessTools.Field(typeof(StatsManager), "saveFileCurrent");
		string text = (string)fieldInfo.GetValue(StatsManager.instance);
		if (string.IsNullOrEmpty(text))
		{
			Debug.LogWarning((object)"[NoSaveDelete] No active save file!");
			return;
		}
		string text2 = Path.Combine(Application.persistentDataPath, "saves", text);
		if (!Directory.Exists(text2))
		{
			Debug.LogError((object)("[NoSaveDelete] Save folder not found: " + text2));
			return;
		}
		string text3 = FindLatestBackup(text2, text);
		if (!string.IsNullOrEmpty(text3))
		{
			try
			{
				string text4 = Path.Combine(text2, text + ".es3");
				if (File.Exists(text4))
				{
					File.Delete(text4);
				}
				File.Copy(text3, text4);
				Debug.Log((object)("[NoSaveDelete] Backup successfully restored from: " + text3));
				MethodInfo method = typeof(StatsManager).GetMethod("LoadGame", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (method != null)
				{
					method.Invoke(StatsManager.instance, new object[2] { text, null });
					Debug.Log((object)("[NoSaveDelete] Called LoadGame() for " + text + ", data updated in memory."));
				}
				else
				{
					Debug.LogWarning((object)"[NoSaveDelete] Unable to find LoadGame method for reflection call!");
				}
				return;
			}
			catch (IOException ex)
			{
				Debug.LogError((object)("[NoSaveDelete] Restore error: " + ex.Message));
				return;
			}
		}
		Debug.LogWarning((object)"[NoSaveDelete] No backup found! Using the standard save.");
	}

	private static string FindLatestBackup(string directory, string saveFileName)
	{
		if (!Directory.Exists(directory))
		{
			Debug.LogError((object)"[NoSaveDelete] Save directory is empty or does not exist!");
			return null;
		}
		string[] files = Directory.GetFiles(directory, saveFileName + "_BACKUP*.es3");
		if (files.Length == 0)
		{
			Debug.LogWarning((object)"[NoSaveDelete] No backup files found.");
			return null;
		}
		Regex regex = new Regex("_BACKUP(\\d+)", RegexOptions.IgnoreCase);
		var anon = (from file in files
			select new
			{
				FilePath = file,
				BackupNumber = ExtractBackupNumber(file, regex)
			} into b
			where b.BackupNumber >= 0
			orderby b.BackupNumber descending
			select b).FirstOrDefault();
		if (anon == null)
		{
			Debug.LogWarning((object)"[NoSaveDelete] Unable to determine the latest backup.");
			return null;
		}
		Debug.Log((object)$"[NoSaveDelete] Selected backup: {anon.FilePath} (number {anon.BackupNumber})");
		return anon.FilePath;
	}

	private static int ExtractBackupNumber(string filePath, Regex regex)
	{
		string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filePath);
		Match match = regex.Match(fileNameWithoutExtension);
		if (match.Success && int.TryParse(match.Groups[1].Value, out var result))
		{
			return result;
		}
		return -1;
	}

	public static void ResetFlags()
	{
		shouldRestoreBackup = false;
		hasLoggedArena = false;
		Debug.Log((object)"[NoSaveDelete] Backup flags have been reset.");
	}
}
[HarmonyPatch(typeof(RunManager), "LeaveToMainMenu")]
public class ResetBackupFlagsOnMainMenuLeave
{
	private static void Prefix()
	{
		object value = AccessTools.Field(typeof(CheckArenaAndRestoreBackup), "shouldRestoreBackup").GetValue(null);
		bool flag = default(bool);
		int num;
		if (value is bool)
		{
			flag = (bool)value;
			num = 1;
		}
		else
		{
			num = 0;
		}
		if (((uint)num & (flag ? 1u : 0u)) != 0)
		{
			CheckArenaAndRestoreBackup.ResetFlags();
			Debug.Log((object)"[NoSaveDelete] The host has left the arena and returned to the main menu. Resetting flags...");
		}
		else
		{
			Debug.Log((object)"[NoSaveDelete] Returning to the main menu. Flags were not set — no reset needed.");
		}
	}
}
[HarmonyPatch(typeof(PlayerAvatar), "PlayerDeath")]
public class AutoLoadSingleplayer
{
	[HarmonyPatch(typeof(PlayerAvatar), "Revive")]
	public class CancelAutoLoadOnRevive
	{
		private static void Prefix()
		{
			if (_cancellationTokenSource != null)
			{
				_cancellationTokenSource.Cancel();
				Debug.Log((object)"[NoSaveDelete] Player revived. Auto-load canceled.");
			}
			PreventSaveGameUltimate.ResetPlayerDied();
		}
	}

	private static CancellationTokenSource _cancellationTokenSource;

	private static async void Prefix()
	{
		if (MyModConfig.AllowGameDelete.Value)
		{
			Debug.Log((object)"[NoSaveDelete] Auto-load disabled due to AllowGameDelete being enabled.");
		}
		else
		{
			if (SemiFunc.IsMultiplayer())
			{
				return;
			}
			if (!SemiFunc.RunIsLevel() && !SemiFunc.RunIsArena())
			{
				Debug.Log((object)"[NoSaveDelete] Player died in lobby/shop. Auto-load disabled.");
				return;
			}
			PreventSaveGameUltimate.SetPlayerDied();
			FieldInfo saveFileField = AccessTools.Field(typeof(StatsManager), "saveFileCurrent");
			string saveFileName = (string)saveFileField.GetValue(StatsManager.instance);
			if (!string.IsNullOrEmpty(saveFileName))
			{
				Debug.Log((object)("[NoSaveDelete] The player has died. Reloading the last save: " + saveFileName));
				_cancellationTokenSource?.Cancel();
				_cancellationTokenSource = new CancellationTokenSource();
				CancellationToken token = _cancellationTokenSource.Token;
				try
				{
					await Task.Delay(4000, token);
					if (!token.IsCancellationRequested)
					{
						SemiFunc.MenuActionSingleplayerGame(saveFileName, (List<string>)null);
						await Task.Delay(1000, token);
						if (!token.IsCancellationRequested)
						{
							ReloadSaveInMemory(saveFileName);
						}
						PreventSaveGameUltimate.ResetPlayerDied();
					}
					return;
				}
				catch (TaskCanceledException)
				{
					Debug.Log((object)"[NoSaveDelete] Auto-load was canceled because the player revived.");
					PreventSaveGameUltimate.ResetPlayerDied();
					return;
				}
			}
			Debug.LogWarning((object)"[NoSaveDelete] No save file to load!");
			PreventSaveGameUltimate.ResetPlayerDied();
		}
	}

	private static void ReloadSaveInMemory(string saveFileName)
	{
		try
		{
			MethodInfo method = typeof(StatsManager).GetMethod("LoadGame", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (method != null)
			{
				method.Invoke(StatsManager.instance, new object[2] { saveFileName, null });
				Debug.Log((object)("[NoSaveDelete] Save Data for " + saveFileName + ", updated in memory."));
			}
			else
			{
				Debug.LogWarning((object)"[NoSaveDelete] Unable to find LoadGame method for memory reload!");
			}
		}
		catch (Exception ex)
		{
			Debug.LogError((object)("[NoSaveDelete] Error reloading save in memory: " + ex.Message));
		}
	}
}
public static class MyModConfig
{
	public static ConfigEntry<bool> AllowPlayerDelete;

	public static ConfigEntry<bool> AllowGameDelete;

	public static ConfigEntry<bool> AutoLoadInMultiplayer;

	public static void Init(ConfigFile config)
	{
		AllowPlayerDelete = config.Bind<bool>("Settings", "AllowPlayerDelete", true, "Allow the player to delete saves? (true - yes, false - no)");
		AllowGameDelete = config.Bind<bool>("Settings", "AllowGameDelete", false, "Allow the game to delete saves? (true - yes, false - no)");
		AutoLoadInMultiplayer = config.Bind<bool>("Settings", "AutoLoadInMultiplayer", false, "Enable automatically load the last save in Multiplayer if ALL players die? (true - yes, false - no)");
	}
}
[HarmonyPatch(typeof(MenuPageSaves), "OnDeleteGame")]
public class MenuPageSavesPatch
{
	public static bool IsPlayerDeletingSave;

	private static bool Prefix()
	{
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		Debug.Log((object)$"Attempt to delete the save. AllowPlayerDelete = {MyModConfig.AllowPlayerDelete.Value}");
		if (!MyModConfig.AllowPlayerDelete.Value)
		{
			Debug.Log((object)"The player is not allowed to delete the save (config prohibits it).");
			MenuManager.instance.PagePopUp("Delete blocked.", Color.red, "You cannot delete the save. Please change the mod config.", "OK", false);
			return false;
		}
		Debug.Log((object)"The player is deleting the save.");
		IsPlayerDeletingSave = true;
		return true;
	}
}
[BepInPlugin("com.PxntxrezStudio.nosavedelete", "NoSaveDelete", "1.3.0")]
public class MyMod : BaseUnityPlugin
{
	private void Awake()
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Expected O, but got Unknown
		MyModConfig.Init(((BaseUnityPlugin)this).Config);
		Harmony val = new Harmony("com.PxntxrezStudio.nosavedelete");
		val.PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Mod NoSaveDelete loaded.");
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Settings can be changed in BepInEx/config/com.PxntxrezStudio.nosavedelete.cfg");
	}
}
[HarmonyPatch(typeof(StatsManager), "SaveFileDelete")]
public class SaveFileDeletePatch
{
	private static bool Prefix(string saveFileName)
	{
		if (MenuPageSavesPatch.IsPlayerDeletingSave)
		{
			Debug.Log((object)("Player delete save " + saveFileName + "."));
			MenuPageSavesPatch.IsPlayerDeletingSave = false;
			return true;
		}
		if (MyModConfig.AllowGameDelete.Value)
		{
			Debug.Log((object)("Game delete save " + saveFileName + " (allowed by config)."));
			return true;
		}
		Debug.Log((object)("The game tried to delete the save " + saveFileName + ", but the mod blocked it."));
		return false;
	}
}
[HarmonyPatch(typeof(StatsManager), "SaveGame")]
public class PreventSaveGameUltimate
{
	private static bool playerJustDied;

	private static bool allPlayersDeadInMultiplayer;

	private static bool Prefix(ref string fileName)
	{
		if (MyModConfig.AllowGameDelete.Value)
		{
			return true;
		}
		if ((Object)(object)RunManager.instance.levelCurrent == (Object)(object)RunManager.instance.levelArena)
		{
			Debug.Log((object)"[NoSaveDelete] Blocking loss of items, charges, HP, and more has been activated! Because AllowGameDelete = false!");
			return false;
		}
		if (allPlayersDeadInMultiplayer && SemiFunc.IsMultiplayer())
		{
			Debug.Log((object)"[NoSaveDelete] Blocking save because all players are dead in multiplayer!");
			return false;
		}
		if (playerJustDied && !SemiFunc.IsMultiplayer())
		{
			Debug.Log((object)"[NoSaveDelete] Blocking save because player just died in singleplayer!");
			return false;
		}
		return true;
	}

	public static void SetPlayerDied()
	{
		playerJustDied = true;
		Debug.Log((object)"[NoSaveDelete] Player death flag set - saves will be blocked");
	}

	public static void ResetPlayerDied()
	{
		playerJustDied = false;
		Debug.Log((object)"[NoSaveDelete] Player death flag reset - saves allowed");
	}

	public static void SetAllPlayersDead()
	{
		allPlayersDeadInMultiplayer = true;
		Debug.Log((object)"[NoSaveDelete] All players dead flag set - multiplayer saves will be blocked");
	}

	public static void ResetAllPlayersDead()
	{
		allPlayersDeadInMultiplayer = false;
		Debug.Log((object)"[NoSaveDelete] All players dead flag reset - multiplayer saves allowed");
	}
}
[HarmonyPatch(typeof(PlayerAvatar), "Start")]
public class QuickReloadInjector
{
	private static void Postfix(PlayerAvatar __instance)
	{
		if ((Object)(object)((Component)__instance).GetComponent<QuickSaveReload>() == (Object)null)
		{
			((Component)__instance).gameObject.AddComponent<QuickSaveReload>();
			Debug.Log((object)"[NoSaveDelete] QuickSaveReload added to player!");
		}
	}
}
public class QuickSaveReload : MonoBehaviour
{
	private bool isReloading = false;

	private void Update()
	{
		if (Input.GetKeyDown((KeyCode)290) && !isReloading)
		{
			Debug.Log((object)"[NoSaveDelete] F9 pressed - Quick reload initiated!");
			QuickReloadSave();
		}
	}

	private async Task QuickReloadSave()
	{
		if (isReloading)
		{
			Debug.Log((object)"[NoSaveDelete] Reload already in progress!");
			return;
		}
		isReloading = true;
		FieldInfo saveFileField = AccessTools.Field(typeof(StatsManager), "saveFileCurrent");
		string saveFileName = (string)saveFileField.GetValue(StatsManager.instance);
		if (string.IsNullOrEmpty(saveFileName))
		{
			Debug.LogWarning((object)"[NoSaveDelete] No active save file to reload!");
			isReloading = false;
			return;
		}
		Debug.Log((object)("[NoSaveDelete] Quick reloading save: " + saveFileName));
		if (SemiFunc.IsMultiplayer())
		{
			if (!PhotonNetwork.IsMasterClient)
			{
				Debug.Log((object)"[NoSaveDelete] Only master client can reload in multiplayer!");
				isReloading = false;
				return;
			}
			PreventSaveGameUltimate.SetAllPlayersDead();
			if ((Object)(object)RunManager.instance.levelCurrent == (Object)(object)RunManager.instance.levelShop)
			{
				Debug.Log((object)"[NoSaveDelete] Quick reload in SHOP. Restarting without backup restore...");
				await Task.Delay(650);
				SemiFunc.MenuActionSingleplayerGame(saveFileName, (List<string>)null);
				PreventSaveGameUltimate.ResetAllPlayersDead();
				isReloading = false;
				return;
			}
			Debug.Log((object)"[NoSaveDelete] Restoring backup for multiplayer quick reload...");
			RestoreBackup(saveFileName);
			await Task.Delay(650);
			SemiFunc.MenuActionSingleplayerGame(saveFileName, (List<string>)null);
			await Task.Delay(1500);
			ReloadSaveInMemory(saveFileName);
			PreventSaveGameUltimate.ResetAllPlayersDead();
			isReloading = false;
		}
		else
		{
			PreventSaveGameUltimate.SetPlayerDied();
			Debug.Log((object)"[NoSaveDelete] Quick reloading in singleplayer...");
			await Task.Delay(650);
			SemiFunc.MenuActionSingleplayerGame(saveFileName, (List<string>)null);
			await Task.Delay(1000);
			ReloadSaveInMemory(saveFileName);
			PreventSaveGameUltimate.ResetPlayerDied();
			isReloading = false;
		}
		Debug.Log((object)"[NoSaveDelete] Quick reload completed!");
	}

	private void RestoreBackup(string saveFileName)
	{
		string text = Path.Combine(Application.persistentDataPath, "saves", saveFileName);
		if (!Directory.Exists(text))
		{
			Debug.LogError((object)("[NoSaveDelete] Save folder not found: " + text));
			return;
		}
		string text2 = FindLatestBackup(text, saveFileName);
		if (!string.IsNullOrEmpty(text2))
		{
			try
			{
				string text3 = Path.Combine(text, saveFileName + ".es3");
				if (File.Exists(text3))
				{
					File.Delete(text3);
				}
				File.Copy(text2, text3);
				Debug.Log((object)("[NoSaveDelete] Backup restored from: " + text2));
				return;
			}
			catch (IOException ex)
			{
				Debug.LogError((object)("[NoSaveDelete] Restore error: " + ex.Message));
				return;
			}
		}
		Debug.LogWarning((object)"[NoSaveDelete] No valid backup found!");
	}

	private string FindLatestBackup(string directory, string saveFileName)
	{
		if (!Directory.Exists(directory))
		{
			return null;
		}
		string[] files = Directory.GetFiles(directory, saveFileName + "_BACKUP*.es3");
		if (files.Length == 0)
		{
			return null;
		}
		Regex regex = new Regex("_BACKUP(\\d+)", RegexOptions.IgnoreCase);
		return (from file in files
			select new
			{
				FilePath = file,
				BackupNumber = ExtractBackupNumber(file, regex)
			} into b
			where b.BackupNumber >= 0
			orderby b.BackupNumber descending
			select b).FirstOrDefault()?.FilePath;
	}

	private int ExtractBackupNumber(string filePath, Regex regex)
	{
		string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filePath);
		Match match = regex.Match(fileNameWithoutExtension);
		if (match.Success && int.TryParse(match.Groups[1].Value, out var result))
		{
			return result;
		}
		return -1;
	}

	private void ReloadSaveInMemory(string saveFileName)
	{
		try
		{
			MethodInfo method = typeof(StatsManager).GetMethod("LoadGame", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (method != null)
			{
				method.Invoke(StatsManager.instance, new object[2] { saveFileName, null });
				Debug.Log((object)("[NoSaveDelete] Save data reloaded in memory for " + saveFileName));
			}
			else
			{
				Debug.LogWarning((object)"[NoSaveDelete] Unable to find LoadGame method for memory reload!");
			}
		}
		catch (Exception ex)
		{
			Debug.LogError((object)("[NoSaveDelete] Error reloading save in memory: " + ex.Message));
		}
	}
}
[HarmonyPatch(typeof(PlayerAvatar), "Start")]
public class InGameSaveSelectorInjector
{
	private static void Postfix(PlayerAvatar __instance)
	{
		if ((Object)(object)((Component)__instance).GetComponent<InGameSaveSelector>() == (Object)null)
		{
			((Component)__instance).gameObject.AddComponent<InGameSaveSelector>();
			Debug.Log((object)"[NoSaveDelete] InGameSaveSelector added to player!");
		}
	}
}
public class InGameSaveSelector : MonoBehaviour
{
	private class SaveFileInfo
	{
		public string fileName;

		public string teamName;

		public string dateTime;

		public int level;

		public int currency;

		public int totalHaul;

		public float timePlayed;

		public List<string> playerNames;

		public bool isValid;

		public List<string> backups;
	}

	private bool showUI = false;

	private Rect windowRect = new Rect((float)(Screen.width / 2 - 400), (float)(Screen.height / 2 - 350), 800f, 700f);

	private Vector2 scrollPosition = Vector2.zero;

	private GUIStyle windowStyle;

	private GUIStyle labelStyle;

	private GUIStyle buttonStyle;

	private GUIStyle currentSaveStyle;

	private GUIStyle saveButtonStyle;

	private GUIStyle deleteButtonStyle;

	private GUIStyle renameButtonStyle;

	private GUIStyle scrollViewStyle;

	private bool stylesInitialized = false;

	private List<SaveFileInfo> saveFiles = new List<SaveFileInfo>();

	private bool savesLoaded = false;

	private string currentSaveFileName = "";

	private bool showLoadConfirmation = false;

	private string selectedSaveToLoad = "";

	private bool showDeleteConfirmation = false;

	private string selectedSaveToDelete = "";

	private bool showNewSaveDialog = false;

	private string newSaveName = "";

	private bool showRenameDialog = false;

	private string selectedSaveToRename = "";

	private string renameSaveNewName = "";

	private void Awake()
	{
		Debug.Log((object)"[NoSaveDelete] InGameSaveSelector Awake() called");
	}

	private void Update()
	{
		if (Input.GetKeyDown((KeyCode)288))
		{
			showUI = !showUI;
			if (showUI)
			{
				Cursor.visible = true;
				Cursor.lockState = (CursorLockMode)0;
				if (!savesLoaded)
				{
					LoadSaveFiles();
				}
			}
			else if (!SemiFunc.IsMainMenu() && !SemiFunc.RunIsLobbyMenu())
			{
				Cursor.visible = false;
				Cursor.lockState = (CursorLockMode)1;
			}
			Debug.Log((object)$"[NoSaveDelete] Save selector UI toggled: {showUI}");
		}
		if (!showUI || !Input.GetKeyDown((KeyCode)27))
		{
			return;
		}
		if (showLoadConfirmation)
		{
			showLoadConfirmation = false;
			return;
		}
		if (showDeleteConfirmation)
		{
			showDeleteConfirmation = false;
			return;
		}
		if (showNewSaveDialog)
		{
			showNewSaveDialog = false;
			return;
		}
		if (showRenameDialog)
		{
			showRenameDialog = false;
			return;
		}
		showUI = false;
		if (!SemiFunc.IsMainMenu() && !SemiFunc.RunIsLobbyMenu())
		{
			Cursor.visible = false;
			Cursor.lockState = (CursorLockMode)1;
		}
	}

	private void OnGUI()
	{
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Expected O, but got Unknown
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		if (showUI)
		{
			InitializeStyles();
			if (showLoadConfirmation)
			{
				DrawLoadConfirmationWindow();
			}
			else if (showDeleteConfirmation)
			{
				DrawDeleteConfirmationWindow();
			}
			else if (showNewSaveDialog)
			{
				DrawNewSaveDialog();
			}
			else if (showRenameDialog)
			{
				DrawRenameDialog();
			}
			else
			{
				windowRect = GUI.Window(54321, windowRect, new WindowFunction(DrawMainWindow), "Save File Manager (No_Save_Delete)", windowStyle);
			}
		}
	}

	private void InitializeStyles()
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Expected O, but got Unknown
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Expected O, but got Unknown
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Expected O, but got Unknown
		//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: Expected O, but got Unknown
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: Expected O, but got Unknown
		//IL_0111: Unknown result type (might be due to invalid IL or missing references)
		//IL_013e: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0166: Expected O, but got Unknown
		//IL_0172: Unknown result type (might be due to invalid IL or missing references)
		//IL_017c: Expected O, but got Unknown
		//IL_0194: Unknown result type (might be due to invalid IL or missing references)
		//IL_019e: Expected O, but got Unknown
		//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b3: Expected O, but got Unknown
		//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c9: Expected O, but got Unknown
		//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0201: Expected O, but got Unknown
		//IL_020c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0216: Expected O, but got Unknown
		//IL_0222: Unknown result type (might be due to invalid IL or missing references)
		//IL_022c: Expected O, but got Unknown
		//IL_0244: Unknown result type (might be due to invalid IL or missing references)
		//IL_024e: Expected O, but got Unknown
		//IL_0259: Unknown result type (might be due to invalid IL or missing references)
		//IL_0263: Expected O, but got Unknown
		//IL_026f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0279: Expected O, but got Unknown
		if (!stylesInitialized)
		{
			windowStyle = new GUIStyle(GUI.skin.window);
			windowStyle.fontSize = 13;
			windowStyle.fontStyle = (FontStyle)1;
			windowStyle.normal.textColor = Color.white;
			labelStyle = new GUIStyle(GUI.skin.label);
			labelStyle.fontSize = 13;
			labelStyle.normal.textColor = Color.white;
			labelStyle.wordWrap = true;
			buttonStyle = new GUIStyle(GUI.skin.button);
			buttonStyle.fontSize = 14;
			buttonStyle.fontStyle = (FontStyle)1;
			buttonStyle.padding = new RectOffset(10, 10, 8, 8);
			currentSaveStyle = new GUIStyle(GUI.skin.box);
			currentSaveStyle.fontSize = 13;
			currentSaveStyle.normal.textColor = Color.green;
			currentSaveStyle.normal.background = MakeTexture(2, 2, new Color(0f, 0.3f, 0f, 0.5f));
			currentSaveStyle.padding = new RectOffset(10, 10, 10, 10);
			saveButtonStyle = new GUIStyle(GUI.skin.button);
			saveButtonStyle.fontSize = 12;
			saveButtonStyle.padding = new RectOffset(6, 6, 5, 5);
			saveButtonStyle.margin = new RectOffset(2, 2, 2, 2);
			deleteButtonStyle = new GUIStyle(GUI.skin.button);
			deleteButtonStyle.fontSize = 12;
			deleteButtonStyle.normal.textColor = Color.red;
			deleteButtonStyle.padding = new RectOffset(6, 6, 5, 5);
			deleteButtonStyle.margin = new RectOffset(2, 2, 2, 2);
			renameButtonStyle = new GUIStyle(GUI.skin.button);
			renameButtonStyle.fontSize = 12;
			renameButtonStyle.padding = new RectOffset(6, 6, 5, 5);
			renameButtonStyle.margin = new RectOffset(2, 2, 2, 2);
			scrollViewStyle = new GUIStyle(GUI.skin.scrollView);
			stylesInitialized = true;
			Debug.Log((object)"[NoSaveDelete] Save selector styles initialized");
		}
	}

	private void DrawMainWindow(int windowID)
	{
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_013b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0140: Unknown result type (might be due to invalid IL or missing references)
		GUILayout.Space(10f);
		FieldInfo fieldInfo = AccessTools.Field(typeof(StatsManager), "saveFileCurrent");
		currentSaveFileName = (string)fieldInfo.GetValue(StatsManager.instance);
		if (!string.IsNullOrEmpty(currentSaveFileName))
		{
			GUILayout.BeginVertical(currentSaveStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Label("✅ Current Save: " + currentSaveFileName, labelStyle, Array.Empty<GUILayoutOption>());
			GUILayout.EndVertical();
			GUILayout.Space(5f);
		}
		GUILayout.Label($"\ud83c\udfae Available Save Files: ({saveFiles.Count})", labelStyle, Array.Empty<GUILayoutOption>());
		GUILayout.Space(5f);
		if (!savesLoaded)
		{
			GUILayout.Label("⏳ Loading saves...", labelStyle, Array.Empty<GUILayoutOption>());
		}
		else if (saveFiles.Count == 0)
		{
			GUILayout.Label("❌ No save files found!", labelStyle, Array.Empty<GUILayoutOption>());
		}
		else
		{
			scrollPosition = GUILayout.BeginScrollView(scrollPosition, scrollViewStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(450f) });
			foreach (SaveFileInfo saveFile in saveFiles)
			{
				DrawSaveFileEntry(saveFile);
				GUILayout.Space(3f);
			}
			GUILayout.EndScrollView();
		}
		GUILayout.Space(10f);
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		if (GUILayout.Button("➕ New Save", buttonStyle, Array.Empty<GUILayoutOption>()))
		{
			newSaveName = "";
			showNewSaveDialog = true;
		}
		if (GUILayout.Button("\ud83d\udd04 Refresh", buttonStyle, Array.Empty<GUILayoutOption>()))
		{
			savesLoaded = false;
			LoadSaveFiles();
		}
		if (GUILayout.Button("❌ Close [F7 / ESC]", buttonStyle, Array.Empty<GUILayoutOption>()))
		{
			showUI = false;
			if (!SemiFunc.IsMainMenu() && !SemiFunc.RunIsLobbyMenu())
			{
				Cursor.visible = false;
				Cursor.lockState = (CursorLockMode)1;
			}
		}
		GUILayout.EndHorizontal();
		GUI.DragWindow();
	}

	private void DrawSaveFileEntry(SaveFileInfo save)
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: 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_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Expected O, but got Unknown
		//IL_0370: Unknown result type (might be due to invalid IL or missing references)
		//IL_0375: Unknown result type (might be due to invalid IL or missing references)
		//IL_037b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0390: Expected O, but got Unknown
		bool flag = save.fileName == currentSaveFileName;
		Color backgroundColor = GUI.backgroundColor;
		if (flag)
		{
			GUI.backgroundColor = new Color(0.2f, 0.8f, 0.2f, 1f);
		}
		GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
		GUI.backgroundColor = backgroundColor;
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		string text = (flag ? "\ud83d\udfe2 " : "⚪ ");
		GUILayout.Label(text + save.teamName, new GUIStyle(labelStyle)
		{
			fontSize = 15,
			fontStyle = (FontStyle)1
		}, Array.Empty<GUILayoutOption>());
		GUILayout.FlexibleSpace();
		if (!flag && save.isValid)
		{
			if (GUILayout.Button("\ud83d\udcc2 Load", saveButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) }))
			{
				selectedSaveToLoad = save.fileName;
				showLoadConfirmation = true;
			}
		}
		else if (flag)
		{
			GUILayout.Label("✅ Active", saveButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) });
		}
		if (save.isValid && GUILayout.Button("Rename", renameButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) }))
		{
			selectedSaveToRename = save.fileName;
			renameSaveNewName = save.teamName;
			showRenameDialog = true;
		}
		if (GUILayout.Button("\ud83d\uddd1\ufe0f Delete", deleteButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) }))
		{
			selectedSaveToDelete = save.fileName;
			showDeleteConfirmation = true;
		}
		GUILayout.EndHorizontal();
		if (save.isValid)
		{
			GUILayout.Label("\ud83d\udcc5 " + save.dateTime, labelStyle, Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label($"\ud83d\ude9a Level: {save.level + 1}", labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(150f) });
			GUILayout.Label($"\ud83d\udcb0 Money: {save.currency}k", labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(150f) });
			GUILayout.Label("⏱\ufe0f Time: " + FormatTime(save.timePlayed), labelStyle, Array.Empty<GUILayoutOption>());
			GUILayout.EndHorizontal();
			GUILayout.Label($"\ud83d\udcb5 Total Haul: ${save.totalHaul}k", labelStyle, Array.Empty<GUILayoutOption>());
			if (save.playerNames != null && save.playerNames.Count > 0)
			{
				string text2 = "\ud83d\udc65 Players: " + string.Join(", ", save.playerNames);
				GUILayout.Label(text2, labelStyle, Array.Empty<GUILayoutOption>());
			}
			if (save.backups != null && save.backups.Count > 0)
			{
				GUILayout.Label($"\ud83d\udcbe Backups: {save.backups.Count}", labelStyle, Array.Empty<GUILayoutOption>());
			}
		}
		else
		{
			GUIStyle val = new GUIStyle(labelStyle);
			val.normal.textColor = Color.red;
			GUILayout.Label("⚠\ufe0f CORRUPTED SAVE FILE", val, Array.Empty<GUILayoutOption>());
		}
		GUILayout.EndVertical();
	}

	private void DrawLoadConfirmationWindow()
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Expected O, but got Unknown
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		Rect val = default(Rect);
		((Rect)(ref val))..ctor((float)(Screen.width / 2 - 200), (float)(Screen.height / 2 - 100), 400f, 200f);
		GUI.Window(54322, val, new WindowFunction(DrawLoadConfirmation), "⚠\ufe0f Load Save?", windowStyle);
	}

	private void DrawLoadConfirmation(int windowID)
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Expected O, but got Unknown
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Expected O, but got Unknown
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Expected O, but got Unknown
		GUILayout.Space(15f);
		GUILayout.Label("Are you sure you want to load this save?", new GUIStyle(labelStyle)
		{
			fontSize = 14,
			alignment = (TextAnchor)4
		}, Array.Empty<GUILayoutOption>());
		GUILayout.Space(5f);
		GUILayout.Label("Save: " + selectedSaveToLoad, new GUIStyle(labelStyle)
		{
			fontSize = 15,
			fontStyle = (FontStyle)1,
			alignment = (TextAnchor)4
		}, Array.Empty<GUILayoutOption>());
		GUILayout.Space(10f);
		GUIStyle val = new GUIStyle(labelStyle);
		val.normal.textColor = Color.yellow;
		val.alignment = (TextAnchor)4;
		GUILayout.Label("⚠\ufe0f Current progress will be lost!", val, Array.Empty<GUILayoutOption>());
		GUILayout.Space(20f);
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		if (GUILayout.Button("✅ Yes, Load Save", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) }))
		{
			LoadSelectedSave();
			showLoadConfirmation = false;
		}
		if (GUILayout.Button("❌ Cancel", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) }))
		{
			showLoadConfirmation = false;
		}
		GUILayout.EndHorizontal();
		GUILayout.Space(10f);
		GUILayout.Label("Press ESC to cancel", labelStyle, Array.Empty<GUILayoutOption>());
	}

	private void DrawDeleteConfirmationWindow()
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Expected O, but got Unknown
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		Rect val = default(Rect);
		((Rect)(ref val))..ctor((float)(Screen.width / 2 - 200), (float)(Screen.height / 2 - 100), 400f, 200f);
		GUI.Window(54323, val, new WindowFunction(DrawDeleteConfirmation), "⚠\ufe0f Delete Save?", windowStyle);
	}

	private void DrawDeleteConfirmation(int windowID)
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Expected O, but got Unknown
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Expected O, but got Unknown
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Expected O, but got Unknown
		GUILayout.Space(15f);
		GUILayout.Label("Are you sure you want to DELETE this save?", new GUIStyle(labelStyle)
		{
			fontSize = 14,
			alignment = (TextAnchor)4
		}, Array.Empty<GUILayoutOption>());
		GUILayout.Space(5f);
		GUILayout.Label("Save: " + selectedSaveToDelete, new GUIStyle(labelStyle)
		{
			fontSize = 15,
			fontStyle = (FontStyle)1,
			alignment = (TextAnchor)4
		}, Array.Empty<GUILayoutOption>());
		GUILayout.Space(10f);
		GUIStyle val = new GUIStyle(labelStyle);
		val.normal.textColor = Color.red;
		val.alignment = (TextAnchor)4;
		GUILayout.Label("⚠\ufe0f This action CANNOT be undone!", val, Array.Empty<GUILayoutOption>());
		GUILayout.Space(20f);
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		if (GUILayout.Button("\ud83d\uddd1\ufe0f Yes, Delete Forever", deleteButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) }))
		{
			DeleteSelectedSave();
			showDeleteConfirmation = false;
		}
		if (GUILayout.Button("❌ Cancel", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) }))
		{
			showDeleteConfirmation = false;
		}
		GUILayout.EndHorizontal();
		GUILayout.Space(10f);
		GUILayout.Label("Press ESC to cancel", labelStyle, Array.Empty<GUILayoutOption>());
	}

	private void DrawNewSaveDialog()
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Expected O, but got Unknown
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		Rect val = default(Rect);
		((Rect)(ref val))..ctor((float)(Screen.width / 2 - 250), (float)(Screen.height / 2 - 100), 500f, 200f);
		GUI.Window(54324, val, new WindowFunction(DrawNewSave), "➕ Create New Save", windowStyle);
	}

	private void DrawNewSave(int windowID)
	{
		GUILayout.Space(15f);
		GUILayout.Label("Enter team name for new save:", labelStyle, Array.Empty<GUILayoutOption>());
		GUILayout.Space(5f);
		GUI.SetNextControlName("NewSaveNameField");
		newSaveName = GUILayout.TextField(newSaveName, 30, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) });
		GUILayout.Space(20f);
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		if (GUILayout.Button("✅ Create Save", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) }))
		{
			CreateNewSave();
		}
		if (GUILayout.Button("❌ Cancel", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) }))
		{
			showNewSaveDialog = false;
		}
		GUILayout.EndHorizontal();
		GUILayout.Space(10f);
		GUILayout.Label("Press ESC to cancel", labelStyle, Array.Empty<GUILayoutOption>());
		GUI.FocusControl("NewSaveNameField");
	}

	private void DrawRenameDialog()
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Expected O, but got Unknown
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		Rect val = default(Rect);
		((Rect)(ref val))..ctor((float)(Screen.width / 2 - 250), (float)(Screen.height / 2 - 100), 500f, 200f);
		GUI.Window(54325, val, new WindowFunction(DrawRename), "✏\ufe0f Rename Save", windowStyle);
	}

	private void DrawRename(int windowID)
	{
		GUILayout.Space(15f);
		GUILayout.Label("Renaming: " + selectedSaveToRename, labelStyle, Array.Empty<GUILayoutOption>());
		GUILayout.Space(5f);
		GUILayout.Label("New team name:", labelStyle, Array.Empty<GUILayoutOption>());
		GUILayout.Space(5f);
		GUI.SetNextControlName("RenameField");
		renameSaveNewName = GUILayout.TextField(renameSaveNewName, 30, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) });
		GUILayout.Space(20f);
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		if (GUILayout.Button("✅ Rename", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) }))
		{
			RenameSelectedSave();
		}
		if (GUILayout.Button("❌ Cancel", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) }))
		{
			showRenameDialog = false;
		}
		GUILayout.EndHorizontal();
		GUILayout.Space(10f);
		GUILayout.Label("Press ESC to cancel", labelStyle, Array.Empty<GUILayoutOption>());
		GUI.FocusControl("RenameField");
	}

	private async Task LoadSaveFiles()
	{
		savesLoaded = false;
		saveFiles.Clear();
		Debug.Log((object)"[NoSaveDelete] Loading save files...");
		Task<List<SaveFolder>> task = StatsManager.instance.SaveFileGetAllAsync();
		await task;
		foreach (SaveFolder saveFolder in task.Result)
		{
			SaveFileInfo info = new SaveFileInfo
			{
				fileName = saveFolder.name,
				backups = saveFolder.backups
			};
			string teamName = StatsManager.instance.SaveFileGetTeamName(saveFolder.name, (string)null);
			string dateTime = StatsManager.instance.SaveFileGetDateAndTime(saveFolder.name, (string)null);
			if (int.TryParse(StatsManager.instance.SaveFileGetRunLevel(saveFolder.name, (string)null), out var level) && int.TryParse(StatsManager.instance.SaveFileGetRunCurrency(saveFolder.name, (string)null), out var currency) && int.TryParse(StatsManager.instance.SaveFileGetTotalHaul(saveFolder.name, (string)null), out var totalHaul))
			{
				info.isValid = true;
				info.teamName = teamName ?? saveFolder.name;
				info.dateTime = dateTime ?? "Unknown date";
				info.level = level;
				info.currency = currency;
				info.totalHaul = totalHaul;
				info.timePlayed = StatsManager.instance.SaveFileGetTimePlayed(saveFolder.name, (string)null);
				info.playerNames = StatsManager.instance.SaveFileGetPlayerNames(saveFolder.name, (string)null);
			}
			else
			{
				info.isValid = false;
				info.teamName = saveFolder.name + " (CORRUPTED)";
				info.dateTime = "N/A";
			}
			saveFiles.Add(info);
		}
		savesLoaded = true;
		Debug.Log((object)$"[NoSaveDelete] Loaded {saveFiles.Count} save files");
	}

	private async void LoadSelectedSave()
	{
		if (string.IsNullOrEmpty(selectedSaveToLoad))
		{
			Debug.LogWarning((object)"[NoSaveDelete] No save selected to load!");
			return;
		}
		Debug.Log((object)("[NoSaveDelete] Loading save: " + selectedSaveToLoad));
		if (SemiFunc.IsMultiplayer())
		{
			PreventSaveGameUltimate.SetAllPlayersDead();
		}
		else
		{
			PreventSaveGameUltimate.SetPlayerDied();
		}
		SaveFileInfo saveInfo = saveFiles.FirstOrDefault((SaveFileInfo s) => s.fileName == selectedSaveToLoad);
		if (saveInfo != null)
		{
			SemiFunc.MenuActionSingleplayerGame(saveInfo.fileName, saveInfo.backups);
			await Task.Delay(1500);
			ReloadSaveInMemory(saveInfo.fileName);
		}
		if (SemiFunc.IsMultiplayer())
		{
			PreventSaveGameUltimate.ResetAllPlayersDead();
		}
		else
		{
			PreventSaveGameUltimate.ResetPlayerDied();
		}
		showUI = false;
		if (!SemiFunc.IsMainMenu() && !SemiFunc.RunIsLobbyMenu())
		{
			Cursor.visible = false;
			Cursor.lockState = (CursorLockMode)1;
		}
	}

	private void ReloadSaveInMemory(string saveFileName)
	{
		try
		{
			MethodInfo method = typeof(StatsManager).GetMethod("LoadGame", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (method != null)
			{
				method.Invoke(StatsManager.instance, new object[2] { saveFileName, null });
				Debug.Log((object)("[NoSaveDelete] Save data reloaded in memory for " + saveFileName));
			}
			else
			{
				Debug.LogWarning((object)"[NoSaveDelete] Unable to find LoadGame method for memory reload!");
			}
		}
		catch (Exception ex)
		{
			Debug.LogError((object)("[NoSaveDelete] Error reloading save in memory: " + ex.Message));
		}
	}

	private void DeleteSelectedSave()
	{
		if (string.IsNullOrEmpty(selectedSaveToDelete))
		{
			Debug.LogWarning((object)"[NoSaveDelete] No save selected to delete!");
			return;
		}
		Debug.Log((object)("[NoSaveDelete] Deleting save from UI: " + selectedSaveToDelete));
		MenuPageSavesPatch.IsPlayerDeletingSave = true;
		StatsManager.instance.SaveFileDelete(selectedSaveToDelete);
		MenuPageSavesPatch.IsPlayerDeletingSave = false;
		savesLoaded = false;
		LoadSaveFiles();
		Debug.Log((object)"[NoSaveDelete] Save deleted successfully!");
	}

	private void CreateNewSave()
	{
		if (string.IsNullOrWhiteSpace(newSaveName))
		{
			newSaveName = "R.E.P.O.";
		}
		Debug.Log((object)("[NoSaveDelete] Creating new save with name: " + newSaveName));
		FieldInfo fieldInfo = AccessTools.Field(typeof(StatsManager), "teamName");
		fieldInfo.SetValue(StatsManager.instance, newSaveName);
		StatsManager.instance.SaveFileCreate();
		showNewSaveDialog = false;
		savesLoaded = false;
		LoadSaveFiles();
		Debug.Log((object)"[NoSaveDelete] New save created successfully!");
	}

	private void RenameSelectedSave()
	{
		if (string.IsNullOrEmpty(selectedSaveToRename) || string.IsNullOrWhiteSpace(renameSaveNewName))
		{
			Debug.LogWarning((object)"[NoSaveDelete] Invalid rename parameters!");
			return;
		}
		Debug.Log((object)("[NoSaveDelete] Renaming save " + selectedSaveToRename + " to " + renameSaveNewName));
		MethodInfo method = typeof(StatsManager).GetMethod("LoadGame", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		if (method != null)
		{
			method.Invoke(StatsManager.instance, new object[2] { selectedSaveToRename, null });
		}
		FieldInfo fieldInfo = AccessTools.Field(typeof(StatsManager), "teamName");
		fieldInfo.SetValue(StatsManager.instance, renameSaveNewName);
		MethodInfo method2 = typeof(StatsManager).GetMethod("SaveGame", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		if (method2 != null)
		{
			method2.Invoke(StatsManager.instance, new object[1] { selectedSaveToRename });
		}
		showRenameDialog = false;
		savesLoaded = false;
		LoadSaveFiles();
		Debug.Log((object)"[NoSaveDelete] Save renamed successfully!");
	}

	private string FormatTime(float timeInSeconds)
	{
		int num = (int)(timeInSeconds / 3600f);
		int num2 = (int)(timeInSeconds % 3600f / 60f);
		if (num > 0)
		{
			return $"{num}h {num2}m";
		}
		return $"{num2}m";
	}

	private Texture2D MakeTexture(int width, int height, Color color)
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Expected O, but got Unknown
		Color[] array = (Color[])(object)new Color[width * height];
		for (int i = 0; i < array.Length; i++)
		{
			array[i] = color;
		}
		Texture2D val = new Texture2D(width, height);
		val.SetPixels(array);
		val.Apply();
		return val;
	}
}
[HarmonyPatch(typeof(MenuPageSaves), "OnNewGame")]
public class RemoveSaveLimitInMenuPatch
{
	private static bool Prefix(MenuPageSaves __instance)
	{
		if (SemiFunc.MainMenuIsMultiplayer())
		{
			SemiFunc.MenuActionHostGame((string)null, (List<string>)null);
		}
		else
		{
			SemiFunc.MenuActionSingleplayerGame((string)null, (List<string>)null);
		}
		Debug.Log((object)"[NoSaveDelete] Creating new save (limit bypass active)");
		return false;
	}
}
[HarmonyPatch(typeof(MenuPageSaves), "Start")]
public class SaveLimitRemovalLogger
{
	private static void Postfix()
	{
		Debug.Log((object)"[NoSaveDelete] ========================================");
		Debug.Log((object)"[NoSaveDelete] Save limit (10 max) has been REMOVED!");
		Debug.Log((object)"[NoSaveDelete] You can now create UNLIMITED saves!");
		Debug.Log((object)"[NoSaveDelete] ========================================");
	}
}