Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of No Save Delete v1.3.1
Plugins/NoSaveDelete.dll
Decompiled 5 months agousing 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] ========================================"); } }