Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of SaveKeeper v1.3.7
Zichen-SaveKeeper-1.3.7.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
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