Decompiled source of SaveKeeper v1.3.7

Zichen-SaveKeeper-1.3.7.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using TMPro;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("Zichen-SaveKeeper-1.3.7")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+b61599c415beda119511ff1b786a29d5346f9ec2")]
[assembly: AssemblyProduct("Zichen-SaveKeeper-1.3.7")]
[assembly: AssemblyTitle("Zichen-SaveKeeper-1.3.7")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public enum DisplayLanguage
{
	中文,
	English
}
[BepInPlugin("zichen.savekeeper", "SaveKeeper", "1.3.7")]
public sealed class ZichenSaveKeeperPlugin : BaseUnityPlugin
{
	private sealed class PendingStartupPopup
	{
		public string Title;

		public Color Color;

		public string Message;

		public int Priority;

		public int Sequence;
	}

	private readonly struct SaveProgressMarker
	{
		public readonly int RunLevel;

		public readonly int SaveLevel;

		public SaveProgressMarker(int runLevel, int saveLevel)
		{
			RunLevel = runLevel;
			SaveLevel = saveLevel;
		}

		public override string ToString()
		{
			int runLevel = RunLevel;
			string text = runLevel.ToString();
			runLevel = SaveLevel;
			return "runLevel=" + text + ", saveLevel=" + runLevel;
		}
	}

	private readonly struct SaveProgressCandidate
	{
		public readonly string Path;

		public readonly bool IsMainSave;

		public readonly int BackupNumber;

		public readonly SaveProgressMarker Progress;

		public SaveProgressCandidate(string path, bool isMainSave, int backupNumber, SaveProgressMarker progress)
		{
			Path = path;
			IsMainSave = isMainSave;
			BackupNumber = backupNumber;
			Progress = progress;
		}
	}

	private sealed class SessionSaveContext
	{
		public bool PublicServerSavesMenuOpen;

		public string PendingNewSaveName;

		public string PublicRoomSaveName;

		public string PublishedHostCopyMetadataSignature;

		public readonly HostCopyAutoSaveState HostCopy = new HostCopyAutoSaveState();

		public void ResetForJoinedRoom()
		{
			HostCopy.ResetForRoomChange();
		}

		public void ResetForLeaveToMainMenu()
		{
			PublicServerSavesMenuOpen = false;
			PendingNewSaveName = null;
			PublicRoomSaveName = null;
			PublishedHostCopyMetadataSignature = null;
			HostCopy.ResetForRoomChange();
		}
	}

	[HarmonyPatch(typeof(MenuPageSaves), "OnDeleteGame")]
	private static class MenuPageSavesOnDeleteGamePatch
	{
		private static bool Prefix()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if (!IsEnabled())
			{
				return true;
			}
			if (allowPlayerDelete != null && allowPlayerDelete.Value)
			{
				playerMenuDeleteInProgress = true;
				return true;
			}
			MenuManager.instance.PagePopUp("SaveKeeper", Color.red, UseChinese() ? "当前配置禁止手动删除存档。" : "Manual save deletion is disabled by configuration.", "OK", false);
			LogWarning("按配置已阻止手动删档。");
			return false;
		}

		private static void Postfix()
		{
			playerMenuDeleteInProgress = false;
		}
	}

	[HarmonyPatch(typeof(MenuPageServerList), "ButtonCreateNew")]
	private static class MenuPageServerListButtonCreateNewPatch
	{
		private static bool Prefix()
		{
			if (!ShouldUsePublicServerSaveSelection())
			{
				return true;
			}
			SemiFunc.MainMenuSetMultiplayer();
			publicServerSavesMenuOpen = true;
			MenuManager.instance.PageCloseAll();
			MenuManager.instance.PageOpen((MenuPageIndex)11, false);
			return false;
		}
	}

	[HarmonyPatch(typeof(MenuPageSaves), "Start")]
	private static class MenuPageSavesStartPatch
	{
		private static void Postfix(MenuPageSaves __instance)
		{
			if ((Object)(object)__instance != (Object)null)
			{
				__instance.maxSaveFiles = 9999;
			}
			if (publicServerSavesMenuOpen && (Object)(object)__instance != (Object)null)
			{
				SetGameModeHeader(__instance, "公开服务器存档 / Public Server Save");
			}
		}
	}

	[HarmonyPatch(typeof(SemiFunc), "MenuActionSingleplayerGame")]
	private static class SemiFuncMenuActionSingleplayerGamePatch
	{
		private static void Prefix(string __0)
		{
			ResetArenaResumeState("准备进入单人存档");
			if (!string.IsNullOrWhiteSpace(__0))
			{
				pendingNewSaveName = null;
			}
		}
	}

	[HarmonyPatch(typeof(SemiFunc), "MenuActionHostGame")]
	private static class SemiFuncMenuActionHostGamePatch
	{
		private static void Prefix(string __0)
		{
			ResetArenaResumeState("准备进入私人房存档");
			if (!string.IsNullOrWhiteSpace(__0))
			{
				pendingNewSaveName = null;
			}
		}
	}

	[HarmonyPatch(typeof(SemiFunc), "MenuActionRandomMatchmaking")]
	private static class SemiFuncMenuActionRandomMatchmakingPatch
	{
		private static void Prefix(string __0)
		{
			ResetArenaResumeState("准备进入随机匹配存档");
			if (!string.IsNullOrWhiteSpace(__0))
			{
				pendingNewSaveName = null;
				return;
			}
			string text2 = (pendingNewSaveName = GenerateNewSaveFileName());
			LogInfo("检测到随机匹配新游戏,等待确认主机身份后初始化存档: " + text2);
		}
	}

	[HarmonyPatch(typeof(MenuPageSaves), "OnNewGame")]
	private static class MenuPageSavesOnNewGamePatch
	{
		private static bool Prefix(MenuPageSaves __instance)
		{
			if (publicServerSavesMenuOpen)
			{
				if ((Object)(object)__instance != (Object)null && __instance.maxSaveFiles > 0 && GetSaveFileCount(__instance) >= __instance.maxSaveFiles)
				{
					return true;
				}
				LogInfo("公开服务器创建,等待游戏自动生成存档。");
				OpenPublicServerCreatePage(null);
				return false;
			}
			return true;
		}

		private static void Postfix()
		{
			if (!publicServerSavesMenuOpen && IsHostAndEnabled())
			{
				pendingNewSaveName = GetCurrentSaveFileName();
				LogInfo("OnNewGame Postfix: " + (pendingNewSaveName ?? "null"));
				ZichenSaveKeeperPlugin instance = Instance;
				if (instance != null)
				{
					((MonoBehaviour)instance).StartCoroutine(EnsureInitialSaveCoroutine(pendingNewSaveName));
				}
			}
		}
	}

	[HarmonyPatch(typeof(MenuPageSaves), "OnLoadGame")]
	private static class MenuPageSavesOnLoadGamePatch
	{
		private static bool Prefix(MenuPageSaves __instance)
		{
			string selectedSaveFileName = GetSelectedSaveFileName(__instance);
			if (!string.IsNullOrWhiteSpace(selectedSaveFileName))
			{
				RecordSaveUsage(selectedSaveFileName);
			}
			if (!publicServerSavesMenuOpen)
			{
				return true;
			}
			OpenPublicServerCreatePage(selectedSaveFileName);
			return false;
		}
	}

	[HarmonyPatch(typeof(MenuPageSaves), "OnGoBack")]
	private static class MenuPageSavesOnGoBackPatch
	{
		private static bool Prefix()
		{
			if (!publicServerSavesMenuOpen)
			{
				return true;
			}
			publicServerSavesMenuOpen = false;
			MenuManager.instance.PageCloseAll();
			MenuManager.instance.PageOpen((MenuPageIndex)14, false);
			return false;
		}
	}

	[HarmonyPatch(typeof(MenuPageServerListCreateNew), "ExitPage")]
	private static class MenuPageServerListCreateNewExitPagePatch
	{
		private static bool Prefix()
		{
			if (!publicServerSavesMenuOpen)
			{
				return true;
			}
			MenuManager.instance.PageCloseAll();
			MenuManager.instance.PageOpen((MenuPageIndex)11, false);
			return false;
		}
	}

	[HarmonyPatch(typeof(MenuPageServerListCreateNew), "ButtonConfirm")]
	private static class MenuPageServerListCreateNewButtonConfirmPatch
	{
		private static void Prefix(MenuPageServerListCreateNew __instance)
		{
			if (!publicServerSavesMenuOpen || !HasPublicServerName(__instance))
			{
				return;
			}
			ResetArenaResumeState("准备创建公开房间");
			ApplyPublicRoomSaveQueue(StatsManager.instance);
			string saveFileNameFromCreatePage;
			if (!string.IsNullOrWhiteSpace(saveFileNameFromCreatePage = GetSaveFileNameFromCreatePage(__instance)))
			{
				LogInfo("公开房间加载已有存档: " + saveFileNameFromCreatePage);
				publicRoomSaveName = saveFileNameFromCreatePage;
				if (StatsManagerCurrentSaveField != null && (Object)(object)StatsManager.instance != (Object)null)
				{
					StatsManagerCurrentSaveField.SetValue(StatsManager.instance, saveFileNameFromCreatePage);
				}
			}
			else
			{
				publicRoomSaveName = null;
				pendingNewSaveName = null;
				LogInfo("公开房间创建新存档:等待原版创建并初始化 runStats。");
			}
			LogInfo("公开房间创建,准备存档上下文: " + (saveFileNameFromCreatePage ?? "(new save)"));
			string publicServerRoomName = GetPublicServerRoomName(__instance);
			if (!string.IsNullOrWhiteSpace(publicServerRoomName) && !string.IsNullOrWhiteSpace(saveFileNameFromCreatePage))
			{
				SetRoomNameForSave(saveFileNameFromCreatePage, publicServerRoomName);
			}
		}

		private static void Postfix(MenuPageServerListCreateNew __instance)
		{
			if (!publicServerSavesMenuOpen || !HasPublicServerName(__instance))
			{
				return;
			}
			string currentSaveFileName = GetCurrentSaveFileName();
			string publicServerRoomName = GetPublicServerRoomName(__instance);
			if (!string.IsNullOrWhiteSpace(currentSaveFileName))
			{
				publicRoomSaveName = currentSaveFileName;
				if (!string.IsNullOrWhiteSpace(publicServerRoomName))
				{
					SetRoomNameForSave(currentSaveFileName, publicServerRoomName);
				}
				if (string.IsNullOrWhiteSpace(GetSaveFileNameFromCreatePage(__instance)))
				{
					pendingNewSaveName = currentSaveFileName;
					LogInfo("公开房间新存档已由原版创建,延迟补首存: " + currentSaveFileName);
					ZichenSaveKeeperPlugin instance = Instance;
					if (instance != null)
					{
						((MonoBehaviour)instance).StartCoroutine(EnsureInitialSaveCoroutine(currentSaveFileName));
					}
				}
				else
				{
					pendingNewSaveName = null;
					LogInfo("公开房间已加载现有存档: " + currentSaveFileName);
				}
			}
			else
			{
				LogWarning("公开房间创建后未取得有效存档名。");
			}
			publicServerSavesMenuOpen = false;
		}
	}

	[HarmonyPatch(typeof(MenuManager), "Start")]
	private static class MenuManagerStartPatch
	{
		private static bool done;

		private static void Postfix()
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			if (done)
			{
				return;
			}
			done = true;
			if (!IsEnabled())
			{
				return;
			}
			if (!compatibilityPopupShown && compatibilityReport.HasIssues && (Object)(object)MenuManager.instance != (Object)null)
			{
				compatibilityPopupShown = true;
				string text = compatibilityReport.BuildPopupMessage();
				if (!string.IsNullOrWhiteSpace(text))
				{
					QueueStartupPopup(UseChinese() ? "SaveKeeper 兼容提示" : "SaveKeeper Compatibility", Color.yellow, text, 2);
				}
			}
			if (!compatibilityReport.HasIssues && IsHostAndEnabled() && showStartupPopup != null && showStartupPopup.Value && (Object)(object)MenuManager.instance != (Object)null)
			{
				QueueStartupPopup(UseChinese() ? "SaveKeeper" : "SaveKeeper", message: UseChinese() ? "SaveKeeper v1.3.7 已加载。\n存档保护功能已启用,只有主机需安装此模组。\n此提示仅弹出一次,后续启动不会再次显示。" : "SaveKeeper v1.3.7 loaded.\nHost-only mod. Save protection is active.\nThis popup only appears once.", color: Color.green, priority: 0);
				showStartupPopup.Value = false;
			}
		}
	}

	[HarmonyPatch(typeof(NetworkConnect), "OnJoinedRoom")]
	private static class NetworkConnectOnJoinedRoomPatch
	{
		private static void Postfix()
		{
			Room currentRoom = PhotonNetwork.CurrentRoom;
			TraceFlow("OnJoinedRoom:enter", "photonRoom=" + (((currentRoom != null) ? currentRoom.Name : null) ?? "null"));
			ResetArenaResumeState("已加入新房间");
			sessionSaveContext.ResetForJoinedRoom();
			TraceFlow("OnJoinedRoom:after-reset");
			if (PhotonNetwork.IsMasterClient)
			{
				PublishHostCopyMetadataToRoom();
				TraceFlow("OnJoinedRoom:published-host-metadata");
			}
			if (!IsEnabled() || !compatibilityReport.RandomMatchmakingAvailable || !IsConnectRandomActive() || !string.IsNullOrWhiteSpace(publicRoomSaveName))
			{
				return;
			}
			if (!PhotonNetwork.IsMasterClient)
			{
				if (!string.IsNullOrWhiteSpace(pendingNewSaveName))
				{
					LogInfo("已加入他人的公开/匹配房间,清理本地待建存档: " + pendingNewSaveName);
					pendingNewSaveName = null;
					TraceFlow("OnJoinedRoom:cleared-pending-save-for-client");
				}
				return;
			}
			if (!string.IsNullOrWhiteSpace(GetCurrentSaveFileName()))
			{
				pendingNewSaveName = null;
				return;
			}
			string text = pendingNewSaveName;
			if (string.IsNullOrWhiteSpace(text))
			{
				text = (pendingNewSaveName = GenerateNewSaveFileName());
			}
			if (StatsManagerCurrentSaveField == null)
			{
				LogWarning("随机匹配房主首存初始化不可用:缺少当前存档字段。");
				return;
			}
			StatsManagerCurrentSaveField.SetValue(StatsManager.instance, text);
			LogInfo("随机匹配创建房间,初始化存档: " + text);
			TraceFlow("OnJoinedRoom:host-initial-save", "save=" + text);
			ZichenSaveKeeperPlugin instance = Instance;
			if (instance != null)
			{
				((MonoBehaviour)instance).StartCoroutine(EnsureInitialSaveCoroutine(text));
			}
			PublishHostCopyMetadataToRoom();
		}
	}

	[HarmonyPatch(typeof(NetworkConnect), "OnConnectedToMaster")]
	private static class NetworkConnectOnConnectedToMasterPatch
	{
		private static void Postfix()
		{
			TraceFlow("OnConnectedToMaster", "photonNick=" + (PhotonNetwork.NickName ?? "null"));
		}
	}

	[HarmonyPatch(typeof(PunManager), "SyncAllDictionaries")]
	private static class PunManagerSyncAllDictionariesPatch
	{
		private static void Prefix()
		{
			PublishHostCopyMetadataToRoom();
		}
	}

	[HarmonyPatch(typeof(PunManager), "ReceiveSyncData")]
	private static class PunManagerReceiveSyncDataPatch
	{
		private static void Postfix(bool __1)
		{
			if (__1 && ShouldCopyHostSaveToLocal() && IsNonHostMultiplayerClient())
			{
				SchedulePendingHostCopyAutoSavePlanBuild();
			}
		}
	}

	[HarmonyPatch(typeof(RunManager), "ChangeLevel")]
	private static class RunManagerChangeLevelPatch
	{
		private static void Prefix(RunManager __instance, ref bool __0, ref bool __1, ref ChangeLevelType __2)
		{
			if (!IsHostAndEnabled())
			{
				return;
			}
			string[] obj = new string[8]
			{
				"[ChangeLevel] _completedLevel=",
				__0.ToString(),
				", _levelFailed=",
				__1.ToString(),
				", changeType=",
				((object)(ChangeLevelType)(ref __2)).ToString(),
				", current=",
				null
			};
			object obj2;
			if (__instance == null)
			{
				obj2 = null;
			}
			else
			{
				Level levelCurrent = __instance.levelCurrent;
				obj2 = ((levelCurrent != null) ? ((Object)levelCurrent).name : null);
			}
			if (obj2 == null)
			{
				obj2 = "null";
			}
			obj[7] = (string)obj2;
			LogInfo(string.Concat(obj));
			string[] obj3 = new string[8]
			{
				"completed=",
				__0.ToString(),
				", failed=",
				__1.ToString(),
				", changeType=",
				((object)(ChangeLevelType)(ref __2)).ToString(),
				", current=",
				null
			};
			object obj4;
			if (__instance == null)
			{
				obj4 = null;
			}
			else
			{
				Level levelCurrent2 = __instance.levelCurrent;
				obj4 = ((levelCurrent2 != null) ? ((Object)levelCurrent2).name : null);
			}
			if (obj4 == null)
			{
				obj4 = "null";
			}
			obj3[7] = (string)obj4;
			TraceFlow("ChangeLevel:prefix", string.Concat(obj3));
			if (__1 && (Object)(object)__instance?.levelCurrent != (Object)null && IsLevelArena(__instance.levelCurrent) && TryPrepareDirectArenaResume(__instance, ref __0, ref __1, ref __2))
			{
				return;
			}
			originalArenaLevelsDuringForcedRace = null;
			if (deathArenaMode == null || deathArenaMode.Value == "官方随机" || (Object)(object)__instance == (Object)null || !__1 || (Object)(object)__instance.levelCurrent == (Object)null || (Object)(object)__instance.levelCurrent == (Object)(object)__instance.levelLobby || IsLevelShop(__instance.levelCurrent) || IsLevelArena(__instance.levelCurrent))
			{
				return;
			}
			string value = deathArenaMode.Value;
			Level val = ((value == "皇冠竞技场") ? FindCrownArenaLevel(__instance.levelArena) : FindArenaRaceLevel(__instance.levelArena));
			if ((Object)(object)val == (Object)null)
			{
				if (!missingRaceArenaLogged)
				{
					missingRaceArenaLogged = true;
					LogWarning("Could not find requested death arena mode '" + value + "'. Keeping the game's original arena selection.");
				}
			}
			else
			{
				originalArenaLevelsDuringForcedRace = new List<Level>(__instance.levelArena);
				__instance.levelArena = new List<Level> { val };
				LogInfo("强制死亡竞技场模式 '" + value + "' -> " + ((Object)val).name);
			}
		}

		private static void Postfix(RunManager __instance)
		{
			if ((Object)(object)__instance != (Object)null && originalArenaLevelsDuringForcedRace != null)
			{
				__instance.levelArena = originalArenaLevelsDuringForcedRace;
				originalArenaLevelsDuringForcedRace = null;
			}
			if (IsHostAndEnabled())
			{
				string text = "null";
				if ((Object)(object)__instance != (Object)null && RunManagerSaveLevelField != null)
				{
					object value = RunManagerSaveLevelField.GetValue(__instance);
					text = ((value != null) ? value.ToString() : "null");
				}
				object obj;
				if (__instance == null)
				{
					obj = null;
				}
				else
				{
					Level levelCurrent = __instance.levelCurrent;
					obj = ((levelCurrent != null) ? ((Object)levelCurrent).name : null);
				}
				if (obj == null)
				{
					obj = "null";
				}
				TraceFlow("ChangeLevel:postfix", "newCurrent=" + (string?)obj + ", saveLevel=" + text);
			}
		}
	}

	[HarmonyPatch(typeof(RunManager), "RestartScene")]
	private static class RunManagerRestartScenePatch
	{
		private static void Prefix(RunManager __instance)
		{
			TraceRestartScene("prefix", __instance);
		}

		private static void Postfix(RunManager __instance)
		{
			TraceRestartScene("postfix", __instance);
		}
	}

	[HarmonyPatch(typeof(NetworkConnect), "OnCreateRoomFailed")]
	private static class NetworkConnectOnCreateRoomFailedPatch
	{
		private static void Prefix(short __0, string __1)
		{
			TraceFlow("OnCreateRoomFailed", "returnCode=" + __0 + ", cause=" + (__1 ?? "null"));
		}
	}

	[HarmonyPatch(typeof(NetworkConnect), "OnJoinRoomFailed")]
	private static class NetworkConnectOnJoinRoomFailedPatch
	{
		private static void Prefix(short __0, string __1)
		{
			TraceFlow("OnJoinRoomFailed", "returnCode=" + __0 + ", cause=" + (__1 ?? "null"));
		}
	}

	[HarmonyPatch(typeof(NetworkConnect), "OnJoinRandomFailed")]
	private static class NetworkConnectOnJoinRandomFailedPatch
	{
		private static void Prefix(short __0, string __1)
		{
			TraceFlow("OnJoinRandomFailed", "returnCode=" + __0 + ", cause=" + (__1 ?? "null"));
		}
	}

	[HarmonyPatch(typeof(NetworkConnect), "OnDisconnected")]
	private static class NetworkConnectOnDisconnectedPatch
	{
		private static void Prefix(object __0)
		{
			TraceFlow("OnDisconnected", "cause=" + (__0?.ToString() ?? "null"));
		}
	}

	[HarmonyPatch(typeof(NetworkManager), "LeavePhotonRoom")]
	private static class NetworkManagerLeavePhotonRoomPatch
	{
		private static void Prefix()
		{
			TraceFlow("NetworkManager.LeavePhotonRoom");
		}
	}

	[HarmonyPatch(typeof(NetworkManager), "TriggerLeavePhotonRoomForced")]
	private static class NetworkManagerTriggerLeavePhotonRoomForcedPatch
	{
		private static void Prefix()
		{
			TraceFlow("NetworkManager.TriggerLeavePhotonRoomForced");
		}
	}

	[HarmonyPatch(typeof(StatsManager), "Awake")]
	private static class StatsManagerAwakePatch
	{
		private static void Postfix(StatsManager __instance)
		{
			if (IsHostAndEnabled())
			{
				ApplyPublicRoomSaveQueue(__instance);
			}
		}
	}

	[HarmonyPatch(typeof(StatsManager), "SaveFileDelete")]
	private static class StatsManagerSaveFileDeletePatch
	{
		private static bool Prefix(string __0)
		{
			if (!IsHostAndEnabled())
			{
				return true;
			}
			if (playerMenuDeleteInProgress)
			{
				playerMenuDeleteInProgress = false;
				RemoveRoomNameForSave(__0);
				LogWarning("放行手动删除存档: " + __0);
				return true;
			}
			if (blockGameDelete == null || !blockGameDelete.Value)
			{
				LogWarning("配置允许游戏删档: " + __0);
				return true;
			}
			if (!string.IsNullOrWhiteSpace(pendingNewSaveName) && __0 == pendingNewSaveName)
			{
				if (!MainSaveFileExists(__0))
				{
					LogWarning("新游戏创建流程中的删档,放行: " + __0 + "(文件尚未写入)");
					return true;
				}
				LogWarning("新存档已存在,拦截创建流程中的删档: " + __0);
				pendingNewSaveName = null;
				return false;
			}
			LogWarning("已阻止游戏自动删档: " + __0);
			return false;
		}
	}

	[HarmonyPatch(typeof(StatsManager), "SaveGame")]
	private static class StatsManagerSaveGamePatch
	{
		private static bool wasFirstSave;

		private static bool Prefix(string __0)
		{
			wasFirstSave = false;
			if (!IsHostAndEnabled())
			{
				return true;
			}
			if (!ShouldBlockDeathOverwrite())
			{
				return true;
			}
			if (!string.IsNullOrWhiteSpace(publicRoomSaveName) && __0 != publicRoomSaveName)
			{
				LogWarning("阻止公开房间生成第二个存档: " + __0 + ",沿用: " + publicRoomSaveName);
				if (MainSaveFileExists(publicRoomSaveName))
				{
					StatsManager instance = StatsManager.instance;
					if (instance != null)
					{
						instance.SaveGame(publicRoomSaveName);
					}
				}
				return false;
			}
			AlignBackupIndexToExistingBackups(StatsManager.instance, __0);
			if (!MainSaveFileExists(__0))
			{
				wasFirstSave = true;
				LogWarning("新存档首次保存,放行: " + __0);
				return true;
			}
			if (IsArenaNow())
			{
				LogWarning("已阻止竞技场/死亡结算流程中的存档: " + __0);
				return false;
			}
			if (playerDeathSaveBlocked && !IsActualMultiplayerSession())
			{
				LogWarning("已阻止单人死亡后的存档覆盖: " + __0);
				return false;
			}
			if (multiplayerDeathSaveBlocked && IsActualMultiplayerSession())
			{
				LogWarning("已阻止多人全灭后的存档覆盖: " + __0);
				return false;
			}
			return true;
		}

		private static void Postfix(string __0, bool __runOriginal)
		{
			if (IsHostAndEnabled() && __runOriginal)
			{
				if (!string.IsNullOrWhiteSpace(pendingNewSaveName) && __0 == pendingNewSaveName)
				{
					LogInfo("新存档已成功写入,关闭创建保护窗口: " + __0);
					pendingNewSaveName = null;
				}
				if (wasFirstSave)
				{
					LogInfo("新存档首次写入完成: " + __0);
				}
				CleanupOldBackups(__0);
				PublishHostCopyMetadataToRoom();
				if (!string.IsNullOrWhiteSpace(__0) && !__0.StartsWith("HOSTCOPY_", StringComparison.Ordinal))
				{
					RecordSaveUsage(__0);
				}
			}
		}
	}

	[HarmonyPatch(typeof(StatsManager), "SaveFileSave")]
	private static class StatsManagerSaveFileSavePatch
	{
		private static void Prefix(StatsManager __instance)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			if (!IsHostAndEnabled() || !ShouldSavePublicRooms() || (Object)(object)__instance == (Object)null || (Object)(object)GameManager.instance == (Object)null || GameManagerLobbyTypeField == null)
			{
				return;
			}
			object value = GameManagerLobbyTypeField.GetValue(GameManager.instance);
			if (!(value is LobbyTypes))
			{
				return;
			}
			LobbyTypes val = (LobbyTypes)value;
			if ((int)val == 0)
			{
				return;
			}
			if (__instance.savedLobbyTypes != null && !__instance.savedLobbyTypes.Contains(val))
			{
				__instance.savedLobbyTypes.Add(val);
			}
			string text = publicRoomSaveName ?? GetCurrentSaveFileName();
			if (!string.IsNullOrWhiteSpace(text))
			{
				string currentSaveFileName = GetCurrentSaveFileName();
				if (!string.IsNullOrWhiteSpace(currentSaveFileName) && currentSaveFileName != text)
				{
					StatsManagerCurrentSaveField?.SetValue(__instance, text);
				}
				LogInfo("准备为非私人房间保存进度: " + text);
			}
		}
	}

	[HarmonyPatch(typeof(PlayerAvatar), "PlayerDeath")]
	private static class PlayerAvatarPlayerDeathPatch
	{
		private static void Prefix()
		{
			if (!IsHostAndEnabled() || !ShouldBlockDeathOverwrite() || IsShopNow())
			{
				return;
			}
			playerDeathSaveBlocked = true;
			LogWarning("检测到单人死亡,已临时阻止存档覆盖。");
			ZichenSaveKeeperPlugin instance = Instance;
			if (instance != null)
			{
				((MonoBehaviour)instance).StartCoroutine(ResetPlayerDeathBlockLater());
			}
			if (restoreSaveAfterSingleplayerDeath == null || !restoreSaveAfterSingleplayerDeath.Value)
			{
				return;
			}
			string currentSaveFileName = GetCurrentSaveFileName();
			if (!string.IsNullOrWhiteSpace(currentSaveFileName))
			{
				ZichenSaveKeeperPlugin instance2 = Instance;
				if (instance2 != null)
				{
					((MonoBehaviour)instance2).StartCoroutine(RestoreSingleplayerSaveAfterDeathLater(currentSaveFileName));
				}
			}
		}
	}

	[HarmonyPatch(typeof(PlayerAvatar), "PlayerDeathRPC")]
	private static class PlayerAvatarPlayerDeathRpcPatch
	{
		private static void Postfix()
		{
			if (ShouldBlockDeathOverwrite() && CanTrackMultiplayerDeathState() && PhotonNetwork.IsMasterClient && AreAllPlayersDead())
			{
				multiplayerDeathSaveBlocked = true;
				LogWarning("检测到所有玩家死亡,已临时阻止多人存档覆盖。");
				ZichenSaveKeeperPlugin instance = Instance;
				if (instance != null)
				{
					((MonoBehaviour)instance).StartCoroutine(ResetMultiplayerDeathBlockLater());
				}
			}
		}
	}

	[HarmonyPatch(typeof(PlayerAvatar), "Revive")]
	private static class PlayerAvatarRevivePatch
	{
		private static void Prefix()
		{
			playerDeathSaveBlocked = false;
			multiplayerDeathSaveBlocked = false;
		}
	}

	[HarmonyPatch(typeof(GameDirector), "Update")]
	private static class GameDirectorUpdatePatch
	{
		private static int frameSkipCounter;

		private static void Postfix()
		{
			frameSkipCounter++;
			if (frameSkipCounter < 60)
			{
				return;
			}
			frameSkipCounter = 0;
			if (!IsEnabled() || restoreBackupAfterArenaReturn == null || !restoreBackupAfterArenaReturn.Value || !PhotonNetwork.IsMasterClient)
			{
				return;
			}
			if (IsArenaNow())
			{
				multiplayerArenaSeen = true;
				TraceFlow("GameDirectorUpdate:arena-seen");
			}
			else if (multiplayerArenaSeen && !multiplayerArenaRestoreRunning && IsLobbyOrLobbyMenuNow())
			{
				LogWarning("从多人竞技场返回,准备恢复存档并自动继续。");
				TraceFlow("GameDirectorUpdate:trigger-restore");
				ZichenSaveKeeperPlugin instance = Instance;
				if (instance != null)
				{
					((MonoBehaviour)instance).StartCoroutine(RestoreBackupAfterArenaReturnLater());
				}
			}
		}
	}

	[HarmonyPatch(typeof(StatsManager), "LoadGame")]
	private static class StatsManagerLoadGamePatch
	{
		private static void Postfix()
		{
			pendingNewSaveName = null;
			if (!manualRestoreRunning && !singleplayerDeathReloadRunning)
			{
				playerDeathSaveBlocked = false;
				multiplayerDeathSaveBlocked = false;
			}
		}
	}

	[HarmonyPatch(typeof(RunManager), "LeaveToMainMenu")]
	private static class RunManagerLeaveToMainMenuPatch
	{
		private static void Prefix()
		{
			TraceFlow("LeaveToMainMenu:prefix");
			playerDeathSaveBlocked = false;
			playerMenuDeleteInProgress = false;
			ResetArenaResumeState("返回主菜单");
			manualRestoreRunning = false;
			singleplayerDeathReloadRunning = false;
			sessionSaveContext.ResetForLeaveToMainMenu();
			TraceFlow("LeaveToMainMenu:after-reset");
		}
	}

	private sealed class CompatibilityReport
	{
		private readonly List<string> disabledFeatures = new List<string>();

		private readonly List<string> details = new List<string>();

		public bool CurrentSaveAvailable = true;

		public bool BackupIndexAvailable = true;

		public bool HostCopyExportAvailable = true;

		public bool HostCopyPlayerNamesAvailable = true;

		public bool DeathStateAvailable = true;

		public bool PublicRoomSaveAvailable = true;

		public bool RandomMatchmakingAvailable = true;

		public bool HostCopyExportFilteringAvailable = true;

		public bool SaveProgressReadAvailable = true;

		public bool StartupPopupCoordinationAvailable = true;

		public bool SceneReloadContextAvailable = true;

		public bool PublicRoomUiAvailable = true;

		public bool InMemoryLoadAvailable = true;

		public bool SaveFileLimitAvailable = true;

		public bool NameChangerInteropAvailable = true;

		public bool PublicRoomDefaultNameAvailable = true;

		public bool HostCopyEncryptionPasswordAvailable = true;

		public bool DiagnosticTraceAvailable = true;

		public bool SaveOrderRecallAvailable = true;

		public bool SaveSelectorMenuAvailable = true;

		public bool LevelStartSnapshotAvailable = true;

		public bool HasIssues => disabledFeatures.Count > 0;

		public static CompatibilityReport CreateHealthy()
		{
			return new CompatibilityReport();
		}

		public static CompatibilityReport Build()
		{
			CompatibilityReport compatibilityReport = new CompatibilityReport();
			if (!RequireField(StatsManagerCurrentSaveField, "StatsManager.saveFileCurrent", compatibilityReport, "当前存档名读取、公开房绑定、首存保护、重载最近存档"))
			{
				compatibilityReport.CurrentSaveAvailable = false;
				compatibilityReport.PublicRoomSaveAvailable = false;
				compatibilityReport.RandomMatchmakingAvailable = false;
			}
			if (!RequireField(StatsManagerBackupIndexField, "StatsManager.backupIndex", compatibilityReport, "备份序号自校准"))
			{
				compatibilityReport.BackupIndexAvailable = false;
			}
			if (!RequireField(StatsManagerDictionaryOfDictionariesField, "StatsManager.dictionaryOfDictionaries", compatibilityReport, "非主机保存房主存档"))
			{
				compatibilityReport.HostCopyExportAvailable = false;
			}
			if (!RequireField(StatsManagerEncryptionPasswordField, "StatsManager.totallyNormalString", compatibilityReport, "房主快照加密密码读取"))
			{
				compatibilityReport.HostCopyEncryptionPasswordAvailable = false;
			}
			bool num = RequireField(StatsManagerDoNotSaveTheseDictionariesField, "StatsManager.doNotSaveTheseDictionaries", compatibilityReport, "房主快照导出过滤与默认值清理");
			bool flag = RequireField(StatsManagerStripTheseDictionariesField, "StatsManager.stripTheseDictionaries", compatibilityReport, "房主快照导出过滤与默认值清理");
			if (!num || !flag)
			{
				compatibilityReport.HostCopyExportFilteringAvailable = false;
			}
			if (!RequireField(PlayerAvatarDeadSetField, "PlayerAvatar.deadSet", compatibilityReport, "多人全灭死亡覆盖保护"))
			{
				compatibilityReport.DeathStateAvailable = false;
			}
			bool num2 = RequireField(PlayerAvatarNameField, "PlayerAvatar.playerName", compatibilityReport, "房主快照玩家名补全");
			bool flag2 = RequireField(PlayerAvatarSteamIdField, "PlayerAvatar.steamID", compatibilityReport, "房主快照玩家名补全");
			if (!num2 || !flag2)
			{
				compatibilityReport.HostCopyPlayerNamesAvailable = false;
			}
			if (!RequireField(GameManagerLobbyTypeField, "GameManager.lobbyType", compatibilityReport, "公开房和随机匹配正常保存"))
			{
				compatibilityReport.PublicRoomSaveAvailable = false;
			}
			if (!RequireField(GameManagerConnectRandomField, "GameManager.connectRandom", compatibilityReport, "随机匹配房主首存初始化"))
			{
				compatibilityReport.RandomMatchmakingAvailable = false;
			}
			bool num3 = RequireField(MenuManagerPagePopUpScheduledField, "MenuManager.pagePopUpScheduled", compatibilityReport, "启动弹窗避让");
			bool flag3 = RequireField(MenuManagerCurrentMenuPageIndexField, "MenuManager.currentMenuPageIndex", compatibilityReport, "启动弹窗避让");
			if (!num3 || !flag3)
			{
				compatibilityReport.StartupPopupCoordinationAvailable = false;
			}
			bool num4 = RequireField(RunManagerLoadLevelField, "RunManager.loadLevel", compatibilityReport, "决斗场后按当前进度继续");
			bool flag4 = RequireField(RunManagerGameOverField, "RunManager.gameOver", compatibilityReport, "当前场景内重载最近存档");
			if (!num4 || !flag4)
			{
				compatibilityReport.SceneReloadContextAvailable = false;
			}
			bool num5 = RequireField(DataDirectorNetworkServerNameField, "DataDirector.networkServerName", compatibilityReport, "调试追踪上下文");
			bool flag5 = RequireField(DataDirectorNetworkJoinServerNameField, "DataDirector.networkJoinServerName", compatibilityReport, "调试追踪上下文");
			bool flag6 = RequireField(RunManagerLobbyJoinField, "RunManager.lobbyJoin", compatibilityReport, "调试追踪上下文");
			bool flag7 = RequireField(RunManagerRestartingField, "RunManager.restarting", compatibilityReport, "调试追踪上下文");
			bool flag8 = RequireField(RunManagerRestartingDoneField, "RunManager.restartingDone", compatibilityReport, "调试追踪上下文");
			bool flag9 = RequireField(RunManagerSaveLevelField, "RunManager.saveLevel", compatibilityReport, "调试追踪上下文");
			if (!num5 || !flag5 || !flag6 || !flag7 || !flag8 || !flag9)
			{
				compatibilityReport.DiagnosticTraceAvailable = false;
			}
			bool num6 = RequireField(MenuManagerCurrentMenuPageField, "MenuManager.currentMenuPage", compatibilityReport, "公开房存档菜单联动");
			bool flag10 = RequireField(MenuPageServerListCreateNewSaveFileNameField, "MenuPageServerListCreateNew.saveFileName", compatibilityReport, "公开房存档菜单联动");
			bool flag11 = RequireField(MenuPageServerListCreateNewMenuPageParentField, "MenuPageServerListCreateNew.menuPageParent", compatibilityReport, "公开房存档菜单联动");
			bool flag12 = RequireNestedField(typeof(MenuPageServerListCreateNew), "menuTextInput", "textCurrent", compatibilityReport, "公开房存档菜单联动");
			bool flag13 = RequireField(MenuPageSavesSaveFilesField, "MenuPageSaves.saveFiles", compatibilityReport, "公开房存档菜单联动");
			bool flag14 = RequireField(MenuPageSavesCurrentSaveFileNameField, "MenuPageSaves.currentSaveFileName", compatibilityReport, "公开房存档菜单联动");
			bool flag15 = RequireNestedProperty(typeof(MenuPageSaves), "gameModeHeader", "text", compatibilityReport, "公开房存档菜单联动");
			if (!num6 || !flag10 || !flag11 || !flag12 || !flag13 || !flag14 || !flag15)
			{
				compatibilityReport.PublicRoomUiAvailable = false;
			}
			if (!RequireField(MenuPageSavesMaxSaveFilesField, "MenuPageSaves.maxSaveFiles", compatibilityReport, "存档上限扩展"))
			{
				compatibilityReport.SaveFileLimitAvailable = false;
			}
			if (!RequireType(SteamClientType, "Steamworks.SteamClient", compatibilityReport, "公开房默认名称读取"))
			{
				compatibilityReport.PublicRoomDefaultNameAvailable = false;
			}
			else if (!RequireProperty(SteamClientNameProperty, SteamClientType, "Name", compatibilityReport, "公开房默认名称读取"))
			{
				compatibilityReport.PublicRoomDefaultNameAvailable = false;
			}
			RequireMethod(typeof(StatsManager), "SaveGame", new Type[1] { typeof(string) }, compatibilityReport, "存档写入保护");
			RequireMethod(typeof(StatsManager), "SaveFileSave", Type.EmptyTypes, compatibilityReport, "公开房和随机匹配正常保存");
			RequireMethod(typeof(StatsManager), "SaveFileDelete", new Type[1] { typeof(string) }, compatibilityReport, "阻止自动删档");
			RequireMethod(typeof(MenuManager), "Start", Type.EmptyTypes, compatibilityReport, "启动提示和兼容提示");
			RequireMethod(typeof(PunManager), "ReceiveSyncData", new Type[3]
			{
				typeof(Hashtable),
				typeof(bool),
				typeof(PhotonMessageInfo)
			}, compatibilityReport, "非主机保存房主存档");
			RequireMethod(typeof(NetworkConnect), "OnJoinedRoom", Type.EmptyTypes, compatibilityReport, "公开房/随机匹配进房初始化");
			RequireMethod(typeof(RunManager), "LeaveToMainMenu", Type.EmptyTypes, compatibilityReport, "会话状态清理");
			bool flag16 = RequireMethod(typeof(StatsManager), "SaveFileGetRunLevel", new Type[2]
			{
				typeof(string),
				typeof(string)
			}, compatibilityReport, "重载最近存档与死亡回档进度比较");
			bool flag17 = RequireMethod(typeof(StatsManager), "SaveFileGetRunStat", new Type[3]
			{
				typeof(string),
				typeof(string),
				typeof(string)
			}, compatibilityReport, "重载最近存档与死亡回档进度比较");
			if (!flag16 || !flag17)
			{
				compatibilityReport.SaveProgressReadAvailable = false;
			}
			if (!RequireMethod(typeof(StatsManager), "LoadGame", new Type[2]
			{
				typeof(string),
				typeof(List<string>)
			}, compatibilityReport, "当前场景内重载最近存档与死亡回档执行"))
			{
				compatibilityReport.InMemoryLoadAvailable = false;
			}
			if (!RequireMethod(typeof(StatsManager), "SaveFileGetAllAsync", Type.EmptyTypes, compatibilityReport, "最近使用存档置顶"))
			{
				compatibilityReport.SaveOrderRecallAvailable = false;
			}
			if (!CheckOptionalNameChangerInterop(compatibilityReport))
			{
				compatibilityReport.NameChangerInteropAvailable = false;
			}
			bool flag18 = RequireMethod(typeof(StatsManager), "SaveFileGetAllAsync", Type.EmptyTypes, compatibilityReport, "F7 存档管理菜单");
			bool flag19 = RequireMethod(typeof(StatsManager), "SaveFileCreate", new Type[2]
			{
				typeof(string),
				typeof(bool)
			}, compatibilityReport, "F7 存档管理菜单");
			bool flag20 = RequireField(typeof(StatsManager).GetField("teamName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic), "StatsManager.teamName", compatibilityReport, "F7 存档管理菜单");
			if (!flag18 || !flag19 || !flag20)
			{
				compatibilityReport.SaveSelectorMenuAvailable = false;
			}
			if (!RequireMethod(typeof(SemiFunc), "OnLevelGenDone", Type.EmptyTypes, compatibilityReport, "关卡开局自动快照"))
			{
				compatibilityReport.LevelStartSnapshotAvailable = false;
			}
			return compatibilityReport;
		}

		public void AddPatchFailure(string featureName, string patchName, string reason)
		{
			AddDisabledFeature(featureName);
			details.Add("Patch failed: " + patchName + " -> " + reason);
		}

		public string BuildLogMessage()
		{
			if (!HasIssues)
			{
				return "Compatibility self-check passed.";
			}
			return "Compatibility self-check found possible game API changes. Affected features: " + string.Join(";", disabledFeatures.Distinct().ToArray());
		}

		public string BuildPopupMessage()
		{
			if (!HasIssues)
			{
				return null;
			}
			bool flag = UseChinese();
			string text = (flag ? "检测到游戏接口可能已变化,SaveKeeper 已进入兼容模式。\n以下功能可能不可用:" : "Some game APIs may have changed. SaveKeeper has entered compatibility mode.\nThe following features may be unavailable:");
			foreach (string item in disabledFeatures.Distinct().Take(6))
			{
				text = text + "\n- " + item;
			}
			return text + (flag ? "\n\n如需使用这些功能,请等待作者适配最新版本。" : "\n\nPlease wait for the mod to be updated for the latest game version.");
		}

		public IEnumerable<string> GetDetailMessages()
		{
			return details.Distinct().ToArray();
		}

		private static bool RequireField(FieldInfo field, string apiName, CompatibilityReport report, string affectedFeature)
		{
			if (field != null)
			{
				return true;
			}
			report.AddDisabledFeature(affectedFeature);
			report.details.Add("Missing field: " + apiName);
			return false;
		}

		private static bool RequireMethod(Type type, string methodName, Type[] parameterTypes, CompatibilityReport report, string affectedFeature)
		{
			if (type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, parameterTypes ?? Type.EmptyTypes, null) != null)
			{
				return true;
			}
			report.AddDisabledFeature(affectedFeature);
			string text = ((parameterTypes == null || parameterTypes.Length == 0) ? "()" : ("(" + string.Join(", ", parameterTypes.Select((Type parameterType) => parameterType.Name).ToArray()) + ")"));
			report.details.Add("Missing method: " + type.FullName + "." + methodName + text);
			return false;
		}

		private static bool RequireNestedField(Type ownerType, string ownerFieldName, string nestedFieldName, CompatibilityReport report, string affectedFeature)
		{
			FieldInfo fieldInfo = ownerType?.GetField(ownerFieldName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			if (fieldInfo == null)
			{
				report.AddDisabledFeature(affectedFeature);
				report.details.Add("Missing field: " + ownerType?.FullName + "." + ownerFieldName);
				return false;
			}
			if (fieldInfo.FieldType.GetField(nestedFieldName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) != null)
			{
				return true;
			}
			report.AddDisabledFeature(affectedFeature);
			report.details.Add("Missing field: " + fieldInfo.FieldType.FullName + "." + nestedFieldName);
			return false;
		}

		private static bool RequireNestedProperty(Type ownerType, string ownerFieldName, string nestedPropertyName, CompatibilityReport report, string affectedFeature)
		{
			FieldInfo fieldInfo = ownerType?.GetField(ownerFieldName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			if (fieldInfo == null)
			{
				report.AddDisabledFeature(affectedFeature);
				report.details.Add("Missing field: " + ownerType?.FullName + "." + ownerFieldName);
				return false;
			}
			if (fieldInfo.FieldType.GetProperty(nestedPropertyName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) != null)
			{
				return true;
			}
			report.AddDisabledFeature(affectedFeature);
			report.details.Add("Missing property: " + fieldInfo.FieldType.FullName + "." + nestedPropertyName);
			return false;
		}

		private static bool RequireType(Type type, string typeName, CompatibilityReport report, string affectedFeature)
		{
			if (type != null)
			{
				return true;
			}
			report.AddDisabledFeature(affectedFeature);
			report.details.Add("Missing type: " + typeName);
			return false;
		}

		private static bool RequireProperty(PropertyInfo property, Type ownerType, string propertyName, CompatibilityReport report, string affectedFeature)
		{
			if (property != null)
			{
				return true;
			}
			report.AddDisabledFeature(affectedFeature);
			report.details.Add("Missing property: " + ownerType?.FullName + "." + propertyName);
			return false;
		}

		private static bool CheckOptionalNameChangerInterop(CompatibilityReport report)
		{
			if (!Chainloader.PluginInfos.TryGetValue("NameChangeREPO", out var value))
			{
				nameChangeRepoStartingNameField = null;
				nameChangeRepoStartingNameValueProperty = null;
				return true;
			}
			object obj = ((value != null) ? value.Instance : null);
			if (obj == null)
			{
				report.AddDisabledFeature("公开房默认名称联动");
				report.details.Add("NameChangeREPO instance is null.");
				return false;
			}
			FieldInfo field = obj.GetType().GetField("StartingName", BindingFlags.Static | BindingFlags.Public);
			if (field == null)
			{
				report.AddDisabledFeature("公开房默认名称联动");
				report.details.Add("Missing field: " + obj.GetType().FullName + ".StartingName");
				return false;
			}
			PropertyInfo property = field.FieldType.GetProperty("Value", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (property != null)
			{
				nameChangeRepoStartingNameField = field;
				nameChangeRepoStartingNameValueProperty = property;
				return true;
			}
			report.AddDisabledFeature("公开房默认名称联动");
			report.details.Add("Missing property: " + field.FieldType.FullName + ".Value");
			return false;
		}

		private void AddDisabledFeature(string feature)
		{
			if (!disabledFeatures.Contains(feature))
			{
				disabledFeatures.Add(feature);
			}
		}
	}

	private sealed class HostCopyMetadata
	{
		public bool PublishedBySaveKeeper;

		public string TeamName;

		public bool TeamNameChanged;

		public float TimePlayed;

		public string DateAndTime;

		public string SourceSaveName;

		public string SourceRoomName;

		public string SourceRoomId;

		public string SourceHostName;

		public string SourceHostUserId;
	}

	private sealed class HostCopyExportPlan
	{
		public string SaveFileName;

		public string ExportSignature;

		public Dictionary<string, Dictionary<string, int>> Snapshot;

		public Dictionary<string, string> PlayerNamesSnapshot;

		public HostCopyMetadata Metadata;

		public string TeamName;

		public bool TeamNameChanged;

		public float TimePlayed;

		public string DateAndTime;

		public int SaveVersion;
	}

	private sealed class HostCopyAutoSaveState
	{
		public bool ExportRunning;

		public string SaveName;

		public string SessionToken;

		public string LastExportSignature;

		public string PendingAutoSaveName;

		public string PendingAutoSaveSignature;

		public HostCopyExportPlan PendingAutoSavePlan;

		public bool PendingPlanBuildRequested;

		public float PendingPlanBuildReadyAt;

		public void ClearPendingAutoSave()
		{
			PendingAutoSaveName = null;
			PendingAutoSaveSignature = null;
			PendingAutoSavePlan = null;
		}

		public void ClearPendingPlanBuild()
		{
			PendingPlanBuildRequested = false;
			PendingPlanBuildReadyAt = 0f;
		}

		public void ResetForRoomChange()
		{
			ExportRunning = false;
			SaveName = null;
			SessionToken = null;
			LastExportSignature = null;
			ClearPendingAutoSave();
			ClearPendingPlanBuild();
		}
	}

	[HarmonyPatch(typeof(StatsManager), "SaveFileGetAllAsync")]
	private static class StatsManagerSaveFileGetAllAsyncPatch
	{
		private static void Postfix(ref Task<List<SaveFolder>> __result)
		{
			if (CanRecallLastUsedSave())
			{
				Task<List<SaveFolder>> task = __result;
				if (task != null)
				{
					__result = WrapAndReorderAsync(task);
				}
			}
		}

		private static async Task<List<SaveFolder>> WrapAndReorderAsync(Task<List<SaveFolder>> inner)
		{
			List<SaveFolder> list = await inner;
			try
			{
				ReorderSaveFoldersByMru(list);
			}
			catch (Exception ex)
			{
				LogWarning("MRU 重排 SaveFileGetAllAsync 结果失败: " + ex.Message);
			}
			return list;
		}
	}

	public sealed class SaveSelectorBehaviour : MonoBehaviour
	{
		private sealed class SaveFileEntry
		{
			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 List<string> Backups;

			public bool IsValid;
		}

		private enum ViewMode
		{
			List,
			ConfirmLoad,
			ConfirmDelete,
			NewSave,
			Rename
		}

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

			private object <>2__current;

			public float seconds;

			public SaveSelectorBehaviour <>4__this;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Expected O, but got Unknown
				int num = <>1__state;
				SaveSelectorBehaviour saveSelectorBehaviour = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSecondsRealtime(seconds);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					saveSelectorBehaviour.isOperationRunning = false;
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

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

		private const float WindowWidth = 860f;

		private const float WindowHeight = 720f;

		private bool windowOpen;

		private bool windowCentered;

		private Rect windowRect = new Rect(0f, 0f, 860f, 720f);

		private Vector2 scrollPosition = Vector2.zero;

		private bool savesLoaded;

		private bool isLoadingSaves;

		private bool isOperationRunning;

		private string statusMessage = string.Empty;

		private Color statusColor = Color.white;

		private float statusUntilUnscaledTime;

		private readonly List<SaveFileEntry> saveFiles = new List<SaveFileEntry>();

		private string currentSaveFileName = string.Empty;

		private ViewMode mode;

		private string selectedSaveToLoad = string.Empty;

		private string selectedSaveToDelete = string.Empty;

		private string newSaveTeamName = string.Empty;

		private string selectedSaveToRename = string.Empty;

		private string renameNewTeamName = string.Empty;

		private bool stylesInit;

		private GUIStyle sWindow;

		private GUIStyle sTitle;

		private GUIStyle sLabel;

		private GUIStyle sLabelDim;

		private GUIStyle sStatus;

		private GUIStyle sCurrentBox;

		private GUIStyle sSection;

		private GUIStyle sBox;

		private GUIStyle sSectionLabel;

		private GUIStyle sCorruptLabel;

		private GUIStyle sWarn;

		private GUIStyle sHostLabel;

		private GUIStyle sTextField;

		private GUIStyle sScroll;

		private GUIStyle sBtnGreen;

		private GUIStyle sBtnRed;

		private GUIStyle sBtnBlue;

		private GUIStyle sBtnNormal;

		private GUIStyle sBtnDisabled;

		private GUIStyle sBtnSmallNormal;

		private GUIStyle sBtnSmallBlue;

		private GUIStyle sBtnSmallRed;

		private GUIStyle sBtnSmallDisabled;

		private Texture2D texDark;

		private Texture2D texMid;

		private Texture2D texLight;

		private Texture2D texSection;

		private Texture2D texCurrent;

		private Texture2D texGreen;

		private Texture2D texRed;

		private Texture2D texBlue;

		private Texture2D texGray;

		private static bool ZH => UseChinese();

		private static string T_WindowTitleList
		{
			get
			{
				if (!ZH)
				{
					return "✦ SaveKeeper";
				}
				return "✦ 存档管家  /  SaveKeeper";
			}
		}

		private static string T_WindowTitleLoad
		{
			get
			{
				if (!ZH)
				{
					return "✦ SaveKeeper / Confirm Load";
				}
				return "✦ 存档管家  /  确认读档";
			}
		}

		private static string T_WindowTitleDelete
		{
			get
			{
				if (!ZH)
				{
					return "✦ SaveKeeper / Confirm Delete";
				}
				return "✦ 存档管家  /  确认删除";
			}
		}

		private static string T_WindowTitleNew
		{
			get
			{
				if (!ZH)
				{
					return "✦ SaveKeeper / New Save";
				}
				return "✦ 存档管家  /  新建存档";
			}
		}

		private static string T_WindowTitleRename
		{
			get
			{
				if (!ZH)
				{
					return "✦ SaveKeeper / Rename Save";
				}
				return "✦ 存档管家  /  重命名存档";
			}
		}

		private static string T_CurrentSavePrefix
		{
			get
			{
				if (!ZH)
				{
					return "Current save: ";
				}
				return "当前存档:";
			}
		}

		private static string T_NoneInBrackets
		{
			get
			{
				if (!ZH)
				{
					return "(none)";
				}
				return "(暂无)";
			}
		}

		private static string T_HostMode
		{
			get
			{
				if (!ZH)
				{
					return "● Host";
				}
				return "● 主机模式";
			}
		}

		private static string T_ViewerMode
		{
			get
			{
				if (!ZH)
				{
					return "○ Read-only (not host)";
				}
				return "○ 仅查看(非主机)";
			}
		}

		private static string T_NonHostHint
		{
			get
			{
				if (!ZH)
				{
					return "You are in someone else's room. Browse only; load / new / rename / delete are disabled.";
				}
				return "当前在他人房间,仅可浏览。读档 / 新建 / 重命名 / 删除按钮已禁用。";
			}
		}

		private static string T_SectionSavesTitle
		{
			get
			{
				if (!ZH)
				{
					return "Saves";
				}
				return "存档列表";
			}
		}

		private static string T_Loading
		{
			get
			{
				if (!ZH)
				{
					return "Loading...";
				}
				return "加载中...";
			}
		}

		private static string T_LoadingFull
		{
			get
			{
				if (!ZH)
				{
					return "Loading saves...";
				}
				return "正在加载存档列表...";
			}
		}

		private static string T_NoSavesFound
		{
			get
			{
				if (!ZH)
				{
					return "No saves found.";
				}
				return "没有找到任何存档。";
			}
		}

		private static string T_BtnNewSave
		{
			get
			{
				if (!ZH)
				{
					return "New Save";
				}
				return "新建存档";
			}
		}

		private static string T_BtnRefresh
		{
			get
			{
				if (!ZH)
				{
					return "Refresh";
				}
				return "刷新列表";
			}
		}

		private static string T_BtnClose
		{
			get
			{
				if (!ZH)
				{
					return "Close  [F7 / ESC]";
				}
				return "关闭  [F7 / ESC]";
			}
		}

		private static string T_BtnLoad
		{
			get
			{
				if (!ZH)
				{
					return "Load";
				}
				return "读档";
			}
		}

		private static string T_BtnRename
		{
			get
			{
				if (!ZH)
				{
					return "Rename";
				}
				return "重命名";
			}
		}

		private static string T_BtnDelete
		{
			get
			{
				if (!ZH)
				{
					return "Delete";
				}
				return "删除";
			}
		}

		private static string T_BtnCurrent
		{
			get
			{
				if (!ZH)
				{
					return "Current";
				}
				return "当前";
			}
		}

		private static string T_BtnConfirmLoad
		{
			get
			{
				if (!ZH)
				{
					return "Load";
				}
				return "确认读档";
			}
		}

		private static string T_BtnConfirmDelete
		{
			get
			{
				if (!ZH)
				{
					return "Delete";
				}
				return "确认删除";
			}
		}

		private static string T_BtnConfirmNew
		{
			get
			{
				if (!ZH)
				{
					return "Create";
				}
				return "创建";
			}
		}

		private static string T_BtnConfirmRename
		{
			get
			{
				if (!ZH)
				{
					return "Rename";
				}
				return "重命名";
			}
		}

		private static string T_BtnCancel
		{
			get
			{
				if (!ZH)
				{
					return "Cancel";
				}
				return "取消";
			}
		}

		private static string T_DateLabel
		{
			get
			{
				if (!ZH)
				{
					return "Date: ";
				}
				return "日期:";
			}
		}

		private static string T_DateUnknown
		{
			get
			{
				if (!ZH)
				{
					return "Unknown";
				}
				return "未知";
			}
		}

		private static string T_LevelLabel
		{
			get
			{
				if (!ZH)
				{
					return "Level: ";
				}
				return "关卡:";
			}
		}

		private static string T_CurrencyLabel
		{
			get
			{
				if (!ZH)
				{
					return "Cash: ";
				}
				return "现金:";
			}
		}

		private static string T_TimeLabel
		{
			get
			{
				if (!ZH)
				{
					return "Time: ";
				}
				return "时长:";
			}
		}

		private static string T_TotalLabel
		{
			get
			{
				if (!ZH)
				{
					return "Total haul: $";
				}
				return "总收益:$";
			}
		}

		private static string T_BackupsLabel
		{
			get
			{
				if (!ZH)
				{
					return "Backups: ";
				}
				return "备份:";
			}
		}

		private static string T_BackupsCountSuffix
		{
			get
			{
				if (!ZH)
				{
					return "";
				}
				return " 份";
			}
		}

		private static string T_BackupsNone
		{
			get
			{
				if (!ZH)
				{
					return "Backups: —";
				}
				return "备份:—";
			}
		}

		private static string T_PlayersLabel
		{
			get
			{
				if (!ZH)
				{
					return "Players: ";
				}
				return "玩家:";
			}
		}

		private static string T_FileNameLabel
		{
			get
			{
				if (!ZH)
				{
					return "File: ";
				}
				return "文件名:";
			}
		}

		private static string T_CountFmt
		{
			get
			{
				if (!ZH)
				{
					return "{0} total";
				}
				return "共 {0} 份";
			}
		}

		private static string T_CorruptedFmt
		{
			get
			{
				if (!ZH)
				{
					return "⚠ Corrupted save ({0})";
				}
				return "⚠ 存档已损坏({0})";
			}
		}

		private static string T_ConfirmLoadHeader
		{
			get
			{
				if (!ZH)
				{
					return "Load this save?";
				}
				return "确定要读取这份存档吗?";
			}
		}

		private static string T_LoadProgressWarn
		{
			get
			{
				if (!ZH)
				{
					return "⚠ Unsaved progress may be lost.";
				}
				return "⚠ 当前未保存的进度可能丢失。";
			}
		}

		private static string T_MultiplayerHint
		{
			get
			{
				if (!ZH)
				{
					return "Multiplayer: will reload inside the current room without dropping teammates.";
				}
				return "多人房:将在当前房间内读档,不会踢掉队友。";
			}
		}

		private static string T_ConfirmDeleteHeader
		{
			get
			{
				if (!ZH)
				{
					return "Delete this save?";
				}
				return "确定要删除这份存档吗?";
			}
		}

		private static string T_DeleteIrreversible
		{
			get
			{
				if (!ZH)
				{
					return "⚠ This cannot be undone!";
				}
				return "⚠ 此操作不可撤销!";
			}
		}

		private static string T_NewSaveHeader
		{
			get
			{
				if (!ZH)
				{
					return "New Save";
				}
				return "新建存档";
			}
		}

		private static string T_NewSavePrompt
		{
			get
			{
				if (!ZH)
				{
					return "Team name (empty = default R.E.P.O.):";
				}
				return "队伍名称(留空则使用默认 R.E.P.O.):";
			}
		}

		private static string T_RenameHeader
		{
			get
			{
				if (!ZH)
				{
					return "Rename Save";
				}
				return "重命名存档";
			}
		}

		private static string T_RenameWho
		{
			get
			{
				if (!ZH)
				{
					return "Renaming: ";
				}
				return "正在重命名:";
			}
		}

		private static string T_RenameNewName
		{
			get
			{
				if (!ZH)
				{
					return "New team name:";
				}
				return "新队伍名称:";
			}
		}

		private static string T_StatusLoadFailFmt
		{
			get
			{
				if (!ZH)
				{
					return "Failed to load saves: {0}";
				}
				return "加载存档列表失败:{0}";
			}
		}

		private static string T_StatusStatsNotReady
		{
			get
			{
				if (!ZH)
				{
					return "Cannot read saves (StatsManager not ready).";
				}
				return "无法读取存档列表(StatsManager 未就绪)。";
			}
		}

		private static string T_StatusGetAllFail
		{
			get
			{
				if (!ZH)
				{
					return "Cannot get saves list.";
				}
				return "无法获取存档列表。";
			}
		}

		private static string T_StatusNonHostNoLoad
		{
			get
			{
				if (!ZH)
				{
					return "Only the host can load saves.";
				}
				return "非主机不可读档。";
			}
		}

		private static string T_StatusNonHostNoDelete
		{
			get
			{
				if (!ZH)
				{
					return "Only the host can delete saves.";
				}
				return "非主机不可删除存档。";
			}
		}

		private static string T_StatusNonHostNoNew
		{
			get
			{
				if (!ZH)
				{
					return "Only the host can create saves.";
				}
				return "非主机不可新建存档。";
			}
		}

		private static string T_StatusNonHostNoRename
		{
			get
			{
				if (!ZH)
				{
					return "Only the host can rename saves.";
				}
				return "非主机不可重命名存档。";
			}
		}

		private static string T_StatusStatsManagerMissing
		{
			get
			{
				if (!ZH)
				{
					return "StatsManager not ready.";
				}
				return "StatsManager 未就绪。";
			}
		}

		private static string T_StatusDeletedFmt
		{
			get
			{
				if (!ZH)
				{
					return "Deleted: {0}";
				}
				return "已删除存档:{0}";
			}
		}

		private static string T_StatusDeleteFailFmt
		{
			get
			{
				if (!ZH)
				{
					return "Delete failed: {0}";
				}
				return "删除存档失败:{0}";
			}
		}

		private static string T_StatusCreatedFmt
		{
			get
			{
				if (!ZH)
				{
					return "Created new save: {0} (will be written to disk once the game starts)";
				}
				return "已创建新存档:{0}(开始游戏后写入磁盘)";
			}
		}

		private static string T_StatusCreateFailFmt
		{
			get
			{
				if (!ZH)
				{
					return "Create failed: {0}";
				}
				return "新建存档失败:{0}";
			}
		}

		private static string T_StatusRenameInvalid
		{
			get
			{
				if (!ZH)
				{
					return "Invalid rename parameters.";
				}
				return "重命名参数无效。";
			}
		}

		private static string T_StatusRenamedFmt
		{
			get
			{
				if (!ZH)
				{
					return "Renamed to: {0}";
				}
				return "已重命名为:{0}";
			}
		}

		private static string T_StatusRenameFailFmt
		{
			get
			{
				if (!ZH)
				{
					return "Rename failed: {0}";
				}
				return "重命名失败:{0}";
			}
		}

		private void Update()
		{
			if (!ShouldEnableSaveSelectorMenu())
			{
				if (windowOpen)
				{
					SetWindowOpen(open: false);
				}
			}
			else if (Input.GetKeyDown((KeyCode)288))
			{
				SetWindowOpen(!windowOpen);
			}
			else
			{
				if (!windowOpen)
				{
					return;
				}
				KeepCursorFree();
				if (Input.GetKeyDown((KeyCode)27))
				{
					if (mode != 0)
					{
						mode = ViewMode.List;
					}
					else
					{
						SetWindowOpen(open: false);
					}
				}
			}
		}

		private void LateUpdate()
		{
			if (windowOpen && ShouldEnableSaveSelectorMenu())
			{
				KeepCursorFree();
			}
		}

		private void OnDestroy()
		{
			if (windowOpen)
			{
				ReleaseCursor();
			}
		}

		private static void TakeCursor()
		{
			try
			{
				if ((Object)(object)CursorManager.instance != (Object)null)
				{
					CursorManager.instance.Unlock(99999f);
				}
			}
			catch
			{
			}
			Cursor.lockState = (CursorLockMode)0;
			Cursor.visible = true;
		}

		private static void ReleaseCursor()
		{
			try
			{
				if (CursorManagerUnlockTimerField != null && (Object)(object)CursorManager.instance != (Object)null)
				{
					CursorManagerUnlockTimerField.SetValue(CursorManager.instance, 0f);
				}
			}
			catch
			{
			}
			try
			{
				if (SemiFunc.IsMainMenu() || SemiFunc.RunIsLobbyMenu())
				{
					Cursor.lockState = (CursorLockMode)0;
					Cursor.visible = true;
					return;
				}
			}
			catch
			{
			}
			Cursor.lockState = (CursorLockMode)1;
			Cursor.visible = false;
		}

		private static void KeepCursorFree()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			if ((int)Cursor.lockState != 0)
			{
				Cursor.lockState = (CursorLockMode)0;
			}
			if (!Cursor.visible)
			{
				Cursor.visible = true;
			}
			try
			{
				if (CursorManagerUnlockTimerField != null && (Object)(object)CursorManager.instance != (Object)null)
				{
					CursorManagerUnlockTimerField.SetValue(CursorManager.instance, 99999f);
				}
			}
			catch
			{
			}
		}

		private void SetWindowOpen(bool open)
		{
			if (windowOpen == open)
			{
				return;
			}
			windowOpen = open;
			if (open)
			{
				windowCentered = false;
				mode = ViewMode.List;
				currentSaveFileName = GetCurrentSaveFileName() ?? string.Empty;
				if (!savesLoaded && !isLoadingSaves)
				{
					LoadSaveFilesAsync();
				}
				TakeCursor();
				LogInfo("F7 打开存档管理菜单(鼠标已解锁)。");
			}
			else
			{
				mode = ViewMode.List;
				ReleaseCursor();
				LogInfo("F7 关闭存档管理菜单。");
			}
		}

		private void OnGUI()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Invalid comparison between Unknown and I4
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Expected O, but got Unknown
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			if (windowOpen && ShouldEnableSaveSelectorMenu())
			{
				EnsureStyles();
				if (Event.current != null && (int)Event.current.type == 7)
				{
					KeepCursorFree();
				}
				if (!windowCentered)
				{
					((Rect)(ref windowRect)).x = ((float)Screen.width - ((Rect)(ref windowRect)).width) * 0.5f;
					((Rect)(ref windowRect)).y = ((float)Screen.height - ((Rect)(ref windowRect)).height) * 0.5f;
					windowCentered = true;
				}
				string text = mode switch
				{
					ViewMode.ConfirmLoad => T_WindowTitleLoad, 
					ViewMode.ConfirmDelete => T_WindowTitleDelete, 
					ViewMode.NewSave => T_WindowTitleNew, 
					ViewMode.Rename => T_WindowTitleRename, 
					_ => T_WindowTitleList, 
				};
				windowRect = GUI.Window(33051, windowRect, new WindowFunction(DrawWindowContents), text, sWindow);
			}
		}

		private void DrawWindowContents(int id)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			switch (mode)
			{
			case ViewMode.ConfirmLoad:
				DrawConfirmLoad();
				break;
			case ViewMode.ConfirmDelete:
				DrawConfirmDelete();
				break;
			case ViewMode.NewSave:
				DrawNewSaveForm();
				break;
			case ViewMode.Rename:
				DrawRenameForm();
				break;
			default:
				DrawListView();
				break;
			}
			GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref windowRect)).width, 28f));
		}

		private void DrawListView()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Expected O, but got Unknown
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			currentSaveFileName = GetCurrentSaveFileName() ?? string.Empty;
			bool flag = !IsActualMultiplayerSession() || PhotonNetwork.IsMasterClient;
			GUILayout.BeginArea(new Rect(14f, 32f, ((Rect)(ref windowRect)).width - 28f, ((Rect)(ref windowRect)).height - 40f));
			GUILayout.BeginVertical(sCurrentBox, Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label(T_CurrentSavePrefix, sTitle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) });
			if (!string.IsNullOrEmpty(currentSaveFileName))
			{
				GUILayout.Label(currentSaveFileName, sHostLabel, Array.Empty<GUILayoutOption>());
			}
			else
			{
				GUILayout.Label(T_NoneInBrackets, sLabelDim, Array.Empty<GUILayoutOption>());
			}
			GUILayout.FlexibleSpace();
			GUILayout.Label(flag ? T_HostMode : T_ViewerMode, flag ? sHostLabel : sWarn, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(160f) });
			GUILayout.EndHorizontal();
			GUILayout.EndVertical();
			if (!flag)
			{
				GUILayout.BeginVertical(sSection, Array.Empty<GUILayoutOption>());
				GUILayout.Label(T_NonHostHint, sWarn, Array.Empty<GUILayoutOption>());
				GUILayout.EndVertical();
			}
			GUILayout.Space(4f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label(T_SectionSavesTitle, sSectionLabel, Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			GUILayout.Label(isLoadingSaves ? T_Loading : string.Format(T_CountFmt, saveFiles.Count), sLabelDim, Array.Empty<GUILayoutOption>());
			GUILayout.EndHorizontal();
			float num = ((Rect)(ref windowRect)).height - 240f;
			scrollPosition = GUILayout.BeginScrollView(scrollPosition, sScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(num) });
			if (isLoadingSaves || !savesLoaded)
			{
				GUILayout.Label(T_LoadingFull, sLabelDim, Array.Empty<GUILayoutOption>());
			}
			else if (saveFiles.Count == 0)
			{
				GUILayout.Label(T_NoSavesFound, sLabelDim, Array.Empty<GUILayoutOption>());
			}
			else
			{
				foreach (SaveFileEntry saveFile in saveFiles)
				{
					DrawSaveFileEntry(saveFile, flag);
					GUILayout.Space(4f);
				}
			}
			GUILayout.EndScrollView();
			if (!string.IsNullOrEmpty(statusMessage) && Time.unscaledTime <= statusUntilUnscaledTime)
			{
				GUILayout.Space(2f);
				GUIStyle val = new GUIStyle(sStatus);
				val.normal.textColor = statusColor;
				GUILayout.Label(statusMessage, val, Array.Empty<GUILayoutOption>());
			}
			GUILayout.Space(6f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUI.enabled = flag && !isOperationRunning;
			if (GUILayout.Button(T_BtnNewSave, flag ? sBtnGreen : sBtnDisabled, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(140f),
				GUILayout.Height(34f)
			}))
			{
				newSaveTeamName = string.Empty;
				mode = ViewMode.NewSave;
			}
			GUI.enabled = !isLoadingSaves;
			if (GUILayout.Button(T_BtnRefresh, sBtnNormal, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(120f),
				GUILayout.Height(34f)
			}))
			{
				LoadSaveFilesAsync();
			}
			GUI.enabled = true;
			GUILayout.FlexibleSpace();
			if (GUILayout.Button(T_BtnClose, sBtnNormal, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(180f),
				GUILayout.Height(34f)
			}))
			{
				SetWindowOpen(open: false);
			}
			GUILayout.EndHorizontal();
			GUILayout.EndArea();
		}

		private void DrawSaveFileEntry(SaveFileEntry entry, bool isHost)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			bool num = entry.FileName == currentSaveFileName;
			GUILayout.BeginVertical(num ? sCurrentBox : sBox, Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUIStyle val = (GUIStyle)(num ? ((object)sHostLabel) : ((object)new GUIStyle(sLabel)
			{
				fontSize = 14,
				fontStyle = (FontStyle)1
			}));
			GUILayout.Label((num ? "● " : "○ ") + (entry.TeamName ?? entry.FileName), val, Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			bool flag = isHost && !isOperationRunning && entry.IsValid;
			if (num)
			{
				GUI.enabled = false;
				GUILayout.Button(T_BtnCurrent, sBtnSmallDisabled, (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(64f),
					GUILayout.Height(26f)
				});
				GUI.enabled = true;
			}
			else if (!entry.IsValid)
			{
				GUI.enabled = false;
				GUILayout.Button("—", sBtnSmallDisabled, (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(64f),
					GUILayout.Height(26f)
				});
				GUI.enabled = true;
			}
			else
			{
				GUI.enabled = flag;
				if (GUILayout.Button(T_BtnLoad, flag ? sBtnSmallBlue : sBtnSmallDisabled, (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(64f),
					GUILayout.Height(26f)
				}))
				{
					selectedSaveToLoad = entry.FileName;
					mode = ViewMode.ConfirmLoad;
				}
				GUI.enabled = true;
			}
			if (entry.IsValid)
			{
				GUI.enabled = isHost && !isOperationRunning;
				if (GUILayout.Button(T_BtnRename, flag ? sBtnSmallNormal : sBtnSmallDisabled, (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(80f),
					GUILayout.Height(26f)
				}))
				{
					selectedSaveToRename = entry.FileName;
					renameNewTeamName = entry.TeamName ?? string.Empty;
					mode = ViewMode.Rename;
				}
				GUI.enabled = true;
			}
			else
			{
				GUILayout.Space(80f);
			}
			GUI.enabled = isHost && !isOperationRunning;
			if (GUILayout.Button(T_BtnDelete, (isHost && !isOperationRunning) ? sBtnSmallRed : sBtnSmallDisabled, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(64f),
				GUILayout.Height(26f)
			}))
			{
				selectedSaveToDelete = entry.FileName;
				mode = ViewMode.ConfirmDelete;
			}
			GUI.enabled = true;
			GUILayout.EndHorizontal();
			if (entry.IsValid)
			{
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label(T_DateLabel + (entry.DateTime ?? T_DateUnknown), sLabel, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(180f) });
				GUILayout.Label(T_LevelLabel + (entry.Level + 1), sLabel, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(110f) });
				GUILayout.Label(T_CurrencyLabel + entry.Currency + "k", sLabel, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(110f) });
				GUILayout.Label(T_TimeLabel + FormatTime(entry.TimePlayed), sLabel, Array.Empty<GUILayoutOption>());
				GUILayout.EndHorizontal();
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label(T_TotalLabel + entry.TotalHaul + "k", sLabel, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(180f) });
				if (entry.Backups != null && entry.Backups.Count > 0)
				{
					GUILayout.Label(T_BackupsLabel + entry.Backups.Count + T_BackupsCountSuffix, sLabel, Array.Empty<GUILayoutOption>());
				}
				else
				{
					GUILayout.Label(T_BackupsNone, sLabelDim, Array.Empty<GUILayoutOption>());
				}
				GUILayout.EndHorizontal();
				if (entry.PlayerNames != null && entry.PlayerNames.Count > 0)
				{
					string separator = (ZH ? "、" : ", ");
					GUILayout.Label(T_PlayersLabel + string.Join(separator, entry.PlayerNames.ToArray()), sLabel, Array.Empty<GUILayoutOption>());
				}
				GUILayout.Label(T_FileNameLabel + entry.FileName, sLabelDim, Array.Empty<GUILayoutOption>());
			}
			else
			{
				GUILayout.Label(string.Format(T_CorruptedFmt, entry.FileName), sCorruptLabel, Array.Empty<GUILayoutOption>());
			}
			GUILayout.EndVertical();
		}

		private void DrawConfirmLoad()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Expected O, but got Unknown
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Expected O, but got Unknown
			GUILayout.BeginArea(new Rect(14f, 36f, ((Rect)(ref windowRect)).width - 28f, ((Rect)(ref windowRect)).height - 44f));
			GUILayout.Space(40f);
			GUIStyle val = new GUIStyle(sLabel)
			{
				alignment = (TextAnchor)4,
				fontSize = 15
			};
			GUILayout.Label(T_ConfirmLoadHeader, val, Array.Empty<GUILayoutOption>());
			GUILayout.Space(8f);
			GUIStyle val2 = new GUIStyle(sTitle)
			{
				alignment = (TextAnchor)4,
				fontSize = 17
			};
			GUILayout.Label(selectedSaveToLoad, val2, Array.Empty<GUILayoutOption>());
			GUILayout.Space(20f);
			GUIStyle val3 = new GUIStyle(sWarn)
			{
				alignment = (TextAnchor)4
			};
			GUILayout.Label(T_LoadProgressWarn, val3, Array.Empty<GUILayoutOption>());
			if (IsActualMultiplayerSession())
			{
				GUIStyle val4 = new GUIStyle(sLabelDim)
				{
					alignment = (TextAnchor)4
				};
				GUILayout.Space(4f);
				GUILayout.Label(T_MultiplayerHint, val4, Array.Empty<GUILayoutOption>());
			}
			GUILayout.FlexibleSpace();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			if (GUILayout.Button(T_BtnConfirmLoad, sBtnGreen, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(160f),
				GUILayout.Height(40f)
			}))
			{
				ExecuteLoadSelectedSave();
			}
			GUILayout.Space(16f);
			if (GUILayout.Button(T_BtnCancel, sBtnNormal, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(140f),
				GUILayout.Height(40f)
			}))
			{
				mode = ViewMode.List;
			}
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
			GUILayout.Space(20f);
			GUILayout.EndArea();
		}

		private void DrawConfirmDelete()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Expected O, but got Unknown
			GUILayout.BeginArea(new Rect(14f, 36f, ((Rect)(ref windowRect)).width - 28f, ((Rect)(ref windowRect)).height - 44f));
			GUILayout.Space(40f);
			GUIStyle val = new GUIStyle(sLabel)
			{
				alignment = (TextAnchor)4,
				fontSize = 15
			};
			GUILayout.Label(T_ConfirmDeleteHeader, val, Array.Empty<GUILayoutOption>());
			GUILayout.Space(8f);
			GUIStyle val2 = new GUIStyle(sTitle)
			{
				alignment = (TextAnchor)4,
				fontSize = 17
			};
			GUILayout.Label(selectedSaveToDelete, val2, Array.Empty<GUILayoutOption>());
			GUILayout.Space(20f);
			GUIStyle val3 = new GUIStyle(sCorruptLabel)
			{
				alignment = (TextAnchor)4,
				fontSize = 15
			};
			GUILayout.Label(T_DeleteIrreversible, val3, Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			if (GUILayout.Button(T_BtnConfirmDelete, sBtnRed, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(160f),
				GUILayout.Height(40f)
			}))
			{
				ExecuteDeleteSelectedSave();
			}
			GUILayout.Space(16f);
			if (GUILayout.Button(T_BtnCancel, sBtnNormal, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(140f),
				GUILayout.Height(40f)
			}))
			{
				mode = ViewMode.List;
			}
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
			GUILayout.Space(20f);
			GUILayout.EndArea();
		}

		private void DrawNewSaveForm()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			GUILayout.BeginArea(new Rect(14f, 36f, ((Rect)(ref windowRect)).width - 28f, ((Rect)(ref windowRect)).height - 44f));
			GUILayout.Space(40f);
			GUIStyle val = new GUIStyle(sLabel)
			{
				alignment = (TextAnchor)4,
				fontSize = 15
			};
			GUILayout.Label(T_NewSaveHeader, val, Array.Empty<GUILayoutOption>());
			GUILayout.Space(20f);
			GUILayout.Label(T_NewSavePrompt, sLabel, Array.Empty<GUILayoutOption>());
			GUILayout.Space(4f);
			GUI.SetNextControlName("ZichenSaveSelector_NewSaveField");
			newSaveTeamName = GUILayout.TextField(newSaveTeamName ?? string.Empty, 30, sTextField, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(34f) });
			GUI.FocusControl("ZichenSaveSelector_NewSaveField");
			GUILayout.FlexibleSpace();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			if (GUILayout.Button(T_BtnConfirmNew, sBtnGreen, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(160f),
				GUILayout.Height(40f)
			}))
			{
				ExecuteCreateNewSave();
			}
			GUILayout.Space(16f);
			if (GUILayout.Button(T_BtnCancel, sBtnNormal, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(140f),
				GUILayout.Height(40f)
			}))
			{
				mode = ViewMode.List;
			}
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
			GUILayout.Space(20f);
			GUILayout.EndArea();
		}

		private void DrawRenameForm()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			GUILayout.BeginArea(new Rect(14f, 36f, ((Rect)(ref windowRect)).width - 28f, ((Rect)(ref windowRect)).height - 44f));
			GUILayout.Space(40f);
			GUIStyle val = new GUIStyle(sLabel)
			{
				alignment = (TextAnchor)4,
				fontSize = 15
			};
			GUILayout.Label(T_RenameHeader, val, Array.Empty<GUILayoutOption>());
			GUILayout.Space(20f);
			GUILayout.Label(T_RenameWho, sLabel, Array.Empty<GUILayoutOption>());
			GUILayout.Label(selectedSaveToRename, sTitle, Array.Empty<GUILayoutOption>());
			GUILayout.Space(12f);
			GUILayout.Label(T_RenameNewName, sLabel, Array.Empty<GUILayoutOption>());
			GUILayout.Space(4f);
			GUI.SetNextControlName("ZichenSaveSelector_RenameField");
			renameNewTeamName = GUILayout.TextField(renameNewTeamName ?? string.Empty, 30, sTextField, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(34f) });
			GUI.FocusControl("ZichenSaveSelector_RenameField");
			GUILayout.FlexibleSpace();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			if (GUILayout.Button(T_BtnConfirmRename, sBtnBlue, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(160f),
				GUILayout.Height(40f)
			}))
			{
				ExecuteRenameSelectedSave();
			}
			GUILayout.Space(16f);
			if (GUILayout.Button(T_BtnCancel, sBtnNormal, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(140f),
				GUILayout.Height(40f)
			}))
			{
				mode = ViewMode.List;
			}
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
			GUILayout.Space(20f);
			GUILayout.EndArea();
		}

		private async Task LoadSaveFilesAsync()
		{
			if (isLoadingSaves)
			{
				return;
			}
			isLoadingSaves = true;
			savesLoaded = false;
			saveFiles.Clear();
			try
			{
				if ((Object)(object)StatsManager.instance == (Object)null || StatsManagerSaveFileGetAllAsyncMethod == null)
				{
					SetStatus(T_StatusStatsNotReady, new Color(1f, 0.55f, 0.55f));
					return;
				}
				Task<List<SaveFolder>> task = (Task<List<SaveFolder>>)StatsManagerSaveFileGetAllAsyncMethod.Invoke(StatsManager.instance, null);
				if (task == null)
				{
					SetStatus(T_StatusGetAllFail, new Color(1f, 0.55f, 0.55f));
					return;
				}
				List<SaveFolder> obj = (await task) ?? new List<SaveFolder>();
				StatsManager instance = StatsManager.instance;
				foreach (SaveFolder item in obj)
				{
					SaveFileEntry saveFileEntry = new SaveFileEntry
					{
						FileName = item.name,
						Backups = item.backups
					};
					string s = instance.SaveFileGetRunLevel(item.name, (string)null);
					string s2 = instance.SaveFileGetRunCurrency(item.name, (string)null);
					string s3 = instance.SaveFileGetTotalHaul(item.name, (string)null);
					if (int.TryParse(s, out var result) && int.TryParse(s2, out var result2) && int.TryParse(s3, out var result3))
					{
						saveFileEntry.IsValid = true;
						saveFileEntry.TeamName = instance.SaveFileGetTeamName(item.name, (string)null) ?? item.name;
						saveFileEntry.DateTime = instance.SaveFileGetDateAndTime(item.name, (string)null) ?? "未知";
						saveFileEntry.Level = result;
						saveFileEntry.Currency = result2;
						saveFileEntry.TotalHaul = result3;
						saveFileEntry.TimePlayed = instance.SaveFileGetTimePlayed(item.name, (string)null);
						try
						{
							saveFileEntry.PlayerNames = instance.SaveFileGetPlayerNames(item.name, (string)null);
						}
						catch
						{
							saveFileEntry.PlayerNames = null;
						}
					}
					else
					{
						saveFileEntry.IsValid = false;
						saveFileEntry.TeamName = item.name;
					}
					saveFiles.Add(saveFileEntry);
				}
				savesLoaded = true;
				LogInfo($"F7 菜单已加载 {saveFiles.Count} 份存档。");
			}
			catch (Exception ex)
			{
				SetStatus(string.Format(T_StatusLoadFailFmt, ex.Message), new Color(1f, 0.55f, 0.55f));
				LogWarning("F7 菜单加载存档失败: " + ex.Message);
			}
			finally
			{
				isLoadingSaves = false;
			}
		}

		private void ExecuteLoadSelectedSave()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			string text = selectedSaveToLoad;
			mode = ViewMode.List;
			if (string.IsNullOrEmpty(text))
			{
				return;
			}
			if (!IsHostAndEnabled())
			{
				SetStatus(T_StatusNonHostNoLoad, new Color(1f, 0.85f, 0.35f));
				return;
			}
			LogInfo("F7 菜单触发读档:" + text);
			try
			{
				if (StatsManagerCurrentSaveField != null && (Object)(object)StatsManager.instance != (Object)null)
				{
					StatsManagerCurrentSaveField.SetValue(StatsManager.instance, text);
				}
			}
			catch (Exception ex)
			{
				LogWarning("F7 切换 saveFileCurrent 失败: " + ex.Message);
			}
			try
			{
				RecordSaveUsage(text);
			}
			catch
			{
			}
			isOperationRunning = true;
			SetWindowOpen(open: false);
			ManualRestoreLatestProgress();
			ZichenSaveKeeperPlugin instance = Instance;
			if (instance != null)
			{
				((MonoBehaviour)instance).StartCoroutine(ClearOperationFlagAfterDelay(2f));
			}
		}

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

		private void ExecuteDeleteSelectedSave()
		{
			//IL_00b4: 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_0087: Unknown result type (might be due to invalid IL or missing references)
			string text = selectedSaveToDelete;
			mode = ViewMode.List;
			if (string.IsNullOrEmpty(text))
			{
				return;
			}
			if (!IsHostAndEnabled())
			{
				SetStatus(T_StatusNonHostNoDelete, new Color(1f, 0.85f, 0.35f));
				return;
			}
			LogInfo("F7 菜单触发删除存档:" + text);
			isOperationRunning = true;
			playerMenuDeleteInProgress = true;
			try
			{
				StatsManager instance = StatsManager.instance;
				if (instance != null)
				{
					instance.SaveFileDelete(text);
				}
				SetStatus(string.Format(T_StatusDeletedFmt, text), new Color(0.5f, 1f, 0.5f));
			}
			catch (Exception ex)
			{
				SetStatus(string.Format(T_StatusDeleteFailFmt, ex.Message), new Color(1f, 0.55f, 0.55f));
				LogWarning("F7 删除失败: " + ex.Message);
			}
			finally
			{
				playerMenuDeleteInProgress = false;
				isOperationRunning = false;
			}
			LoadSaveFilesAsync();
		}

		private void ExecuteCreateNewSave()
		{
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			string text = (string.IsNullOrWhiteSpace(newSaveTeamName) ? "R.E.P.O." : newSaveTeamName.Trim());
			mode = ViewMode.List;
			if (!IsHostAndEnabled())
			{
				SetStatus(T_StatusNonHostNoNew, new Color(1f, 0.85f, 0.35f));
				return;
			}
			if ((Object)(object)StatsManager.instance == (Object)null || StatsManagerSaveFileCreateMethod == null)
			{
				SetStatus(T_StatusStatsManagerMissing, new Color(1f, 0.55f, 0.55f));
				return;
			}
			LogInfo("F7 菜单创建新存档,队伍名:" + text);
			isOperationRunning = true;
			try
			{
				if (StatsManagerTeamNameField != null)
				{
					StatsManagerTeamNameField.SetValue(StatsManager.instance, text);
				}
				StatsManagerSaveFileCreateMethod.Invoke(StatsManager.instance, new object[2]
				{
					string.Empty,
					false
				});
				string text2 = GetCurrentSaveFileName();
				if (!string.IsNullOrEmpty(text2))
				{
					RecordSaveUsage(text2);
				}
				SetStatus(string.Format(T_StatusCreatedFmt, text), new Color(0.5f, 1f, 0.5f));
			}
			catch (Exception ex)
			{
				SetStatus(string.Format(T_StatusCreateFailFmt, ex.Message), new Color(1f, 0.55f, 0.55f));
				LogWarning("F7 新建失败: " + ex.Message);
			}
			finally
			{
				isOperationRunning = false;
			}
			LoadSaveFilesAsync();
		}

		private void ExecuteRenameSelectedSave()
		{
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			string text = selectedSaveToRename;
			string text2 = (renameNewTeamName ?? string.Empty).Trim();
			mode = ViewMode.List;
			if (string.IsNullOrEmpty(text) || string.IsNullOrWhiteSpace(text2))
			{
				SetStatus(T_StatusRenameInvalid, new Color(1f, 0.85f, 0.35f));
				return;
			}
			if (!IsHostAndEnabled())
			{
				SetStatus(T_StatusNonHostNoRename, new Color(1f, 0.85f, 0.35f));
				return;
			}
			LogInfo("F7 菜单重命名存档 " + text + " → " + text2);
			isOperationRunning = true;
			try
			{
				StatsManager instance = StatsManager.instance;
				if ((Object)(object)instance == (Object)null)
				{
					SetStatus(T_StatusStatsManagerMissing, new Color(1f, 0.55f, 0.55f));
					return;
				}
				string value = StatsManagerCurrentSaveField?.GetValue(instance) as string;
				if (StatsManagerLoadGameMethod != null)
				{
					StatsManagerLoadGameMethod.Invoke(instance, new object[2] { text, null });
				}
				if (StatsManagerTeamNameField != null)
				{
					StatsManagerTeamNameField.SetValue(instance, text2);
				}
				typeof(StatsManager).GetField("teamNameChanged", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.SetValue(instance, true);
				instance.SaveGame(text);
				if (!string.IsNullOrEmpty(value))
				{
					StatsManagerCurrentSaveField?.SetValue(instance, value);
				}
				SetStatus(string.Format(T_StatusRenamedFmt, text2), new Color(0.5f, 1f, 0.5f));
			}
			catch (Exception ex)
			{
				SetStatus(string.Format(T_StatusRenameFailFmt, ex.Message), new Color(1f, 0.55f, 0.55f));
				LogWarning("F7 重命名失败: " + ex.Message);
			}
			finally
			{
				isOperationRunning = false;
			}
			LoadSaveFilesAsync();
		}

		private void SetStatus(string message, Color color)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			statusMessage = message;
			statusColor = color;
			statusUntilUnscaledTime = Time.unscaledTime + 5f;
		}

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

		private void EnsureStyles()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Expected O, but got Unknown
			//IL_01ae: Expected O, but got Unknown
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Expected O, but got Unknown
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Expected O, but got Unknown
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Expected O, but got Unknown
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Expected O, but got Unknown
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: Expected O, but got Unknown
			//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_030f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0316: Unknown result type (might be due to invalid IL or missing references)
			//IL_0320: Expected O, but got Unknown
			//IL_0320: Unknown result type (might be due to invalid IL or missing references)
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			//IL_032f: Expected O, but got Unknown
			//IL_0334: Expected O, but got Unknown
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0344: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: Unknown result type (might be due to invalid IL or missing references)
			//IL_035b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0365: Unknown result type (might be due to invalid IL or missing references)
			//IL_036c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0376: Expected O, but got Unknown
			//IL_0376: 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_0385: Expected O, but got Unknown
			//IL_038a: Expected O, but got Unknown
			//IL_0395: Unknown result type (might be due to invalid IL or missing references)
			//IL_039a: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cc: Expected O, but got Unknown
			//IL_03d1: Expected O, but got Unknown
			//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0405: Unknown result type (might be due to invalid IL or missing references)
			//IL_0414: Expected O, but got Unknown
			//IL_041b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0425: Expected O, but got Unknown
			//IL_043f: Unknown result type (might be due to invalid IL or missing references)
			//IL_045c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0466: Expected O, but got Unknown
			//IL_0480: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ff: Expected O, but got Unknown
			//IL_0504: Expected O, but got Unknown
			//IL_050f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0519: Expected O, but got Unknown
			//IL_052f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0557: Unknown result type (might be due to invalid IL or missing references)
			//IL_057f: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0600: Unknown result type (might be due to invalid IL or missing references)
			//IL_0624: Unknown result type (might be due to invalid IL or missing references)
			//IL_0648: Unknown result type (might be due to invalid IL or missing references)
			//IL_0668: Unknown result type (might be due to invalid IL or missing references)
			//IL_0690: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e5: Unknown