using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
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.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
[HarmonyPatch(typeof(PlayerAvatar), "PlayerDeathRPC")]
public class AutoLoadMultiplayer
{
private static async void Postfix()
{
if (MyModConfig.AllowGameDelete.Value)
{
Debug.Log((object)"[NoSaveDelete] Auto-load disabled due to AllowGameDelete being enabled.");
}
else
{
if (!SemiFunc.IsMultiplayer())
{
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)
{
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!");
return;
}
Debug.Log((object)"[NoSaveDelete] All players died. Restart save...");
await Task.Delay(900);
SemiFunc.MenuActionSingleplayerGame(saveFileName);
}
}
}
}
[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.");
}
}
}
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;
}
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);
}
return;
}
catch (TaskCanceledException)
{
Debug.Log((object)"[NoSaveDelete] Auto-load was canceled because the player revived.");
return;
}
}
Debug.LogWarning((object)"[NoSaveDelete] No save file to load!");
}
}
}
public static class MyModConfig
{
public static ConfigEntry<bool> AllowPlayerDelete;
public static ConfigEntry<bool> AllowGameDelete;
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)");
}
}
[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");
return false;
}
Debug.Log((object)"The player is deleting the save.");
IsPlayerDeletingSave = true;
return true;
}
}
[BepInPlugin("com.pxntxrez.nosavedelete", "NoSaveDeleteMod", "1.1.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.pxntxrez.nosavedelete");
val.PatchAll();
((BaseUnityPlugin)this).Logger.LogInfo((object)"Mod NoSaveDelete loaded.");
((BaseUnityPlugin)this).Logger.LogInfo((object)"Settings can be changed in BepInEx/config/com.pxntxrez.nosavedelete.cfg");
}
}
[HarmonyPatch(typeof(RunManager), "ChangeLevel")]
public class RunManagerPatch
{
private static void Postfix(ChangeLevelType _changeLevelType)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0003: Invalid comparison between Unknown and I4
if ((int)_changeLevelType == 4)
{
Debug.Log((object)"The player returned to the main menu. We allow the game to delete the save.");
MyModConfig.AllowGameDelete.Value = true;
}
else
{
Debug.Log((object)"The player has entered the game. We block the game from deleting the save.");
MyModConfig.AllowGameDelete.Value = false;
}
((ConfigEntryBase)MyModConfig.AllowGameDelete).ConfigFile.Save();
}
}
[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;
}
}