using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Threading.Tasks; using BTD_Mod_Helper; using BTD_Mod_Helper.Api; using BTD_Mod_Helper.Api.Components; using BTD_Mod_Helper.Api.Helpers; using BTD_Mod_Helper.Api.ModOptions; using BTD_Mod_Helper.Extensions; using HarmonyLib; using Il2CppAssets.Scripts.Data.Legends; using Il2CppAssets.Scripts.Models; using Il2CppAssets.Scripts.Models.Artifacts; using Il2CppAssets.Scripts.Models.Profile; using Il2CppAssets.Scripts.Models.ServerEvents; using Il2CppAssets.Scripts.Simulation; using Il2CppAssets.Scripts.Simulation.Artifacts; using Il2CppAssets.Scripts.Simulation.Input; using Il2CppAssets.Scripts.Simulation.SimulationBehaviors; using Il2CppAssets.Scripts.Simulation.Towers; using Il2CppAssets.Scripts.Unity; using Il2CppAssets.Scripts.Unity.Menu; using Il2CppAssets.Scripts.Unity.UI_New.GameOver; using Il2CppAssets.Scripts.Unity.UI_New.InGame; using Il2CppAssets.Scripts.Unity.UI_New.InGame.TowerSelectionMenu; using Il2CppAssets.Scripts.Unity.UI_New.Pause; using Il2CppAssets.Scripts.Unity.UI_New.Popups; using Il2CppAssets.Scripts.Utils; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppNewtonsoft.Json; using Il2CppNinjaKiwi.GUTS.Models.ContentBrowser; using Il2CppNinjaKiwi.LiNK.Client; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using MelonLoader; using Microsoft.CodeAnalysis; using TimeMachine; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: MelonInfo(typeof(TimeMachineMod), "Time Machine", "1.1.6", "doombubbles", null)] [assembly: MelonGame("Ninja Kiwi", "BloonsTD6")] [assembly: MelonGame("Ninja Kiwi", "BloonsTD6-Epic")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("TimeMachine")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+74ad0a82f8a00b3d55a14bbf6b7a9fde21af8313")] [assembly: AssemblyProduct("TimeMachine")] [assembly: AssemblyTitle("TimeMachine")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [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; } } } namespace TimeMachine { public static class ModHelperData { public const string WorksOnVersion = "54.2"; public const string Version = "1.1.6"; public const string Name = "Time Machine"; public const string Description = "Stores backups as you play, allowing you to travel back in time to any previous round you passed (even if you just lost!)"; public const string RepoOwner = "doombubbles"; public const string PrevRepoName = "time-machine"; public const string RepoName = "TimeMachine"; } [HarmonyPatch(typeof(InGame), "RoundEnd")] internal static class InGame_RoundEnd { [HarmonyPostfix] private static void Postfix(int completedRound, int highestCompletedRound) { if (InGame.instance.GameId == 0) { ModHelper.Warning((object)"This save is too old to create Time Machine backups for!"); } else { TimeMachineMod.SaveRound(completedRound, highestCompletedRound); } } } [HarmonyPatch(typeof(PauseScreen), "Open")] internal static class PauseScreen_Open { [HarmonyPostfix] private static void Postfix(PauseScreen __instance) { if (!InGameData.CurrentGame.IsSandbox && !(InGameData.CurrentGame.selectedMode == "MapEditor")) { GameObject gameObject = ((Component)__instance.sidePanel.transform.parent).gameObject; TimeMachineMod.CreateTimelineUI(gameObject); } } } [HarmonyPatch(typeof(DefeatScreen), "Open")] internal static class DefeatScreen_Open { [HarmonyPostfix] private static void Postfix(DefeatScreen __instance) { TimeMachineMod.CreateTimelineUI(__instance.regularObject, -50); } } [HarmonyPatch(typeof(BossDefeatScreen), "Open")] internal static class BossDefeatScreen_Open { [HarmonyPostfix] private static void Postfix(BossDefeatScreen __instance) { TimeMachineMod.CreateTimelineUI(((Component)((GameMenu)__instance).commonPanel).gameObject, -50); } } [HarmonyPatch(typeof(RogueDefeatScreen), "Open")] internal static class RogueDefeatScreen_Open { [HarmonyPostfix] private static void Postfix(RogueDefeatScreen __instance) { TimeMachineMod.CreateTimelineUI(((Component)((GameMenu)__instance).commonPanel).gameObject, -50); } } [HarmonyPatch(typeof(RogueInstaInventory), "GetSaveMetaData")] internal static class RogueInstaInventory_GetSaveMetaData { [HarmonyPostfix] internal static void Postfix(RogueInstaInventory __instance, Dictionary metaData) { Enumerator enumerator = __instance.instas.GetEnumerator(); while (enumerator.MoveNext()) { RogueInstaMonkey current = enumerator.Current; metaData["RogueCooldown_" + current.uniqueId] = current.currentCooldown.ToString(); } } } [HarmonyPatch(typeof(RogueInstaInventory), "SetSaveMetaData")] internal static class RogueInstaInventory_SetSaveMetaData { [HarmonyPostfix] internal static void Postfix(RogueInstaInventory __instance, Dictionary metaData) { Enumerator enumerator = __instance.instas.GetEnumerator(); string s = default(string); while (enumerator.MoveNext()) { RogueInstaMonkey current = enumerator.Current; if (metaData.TryGetValue("RogueCooldown_" + current.uniqueId, ref s) && int.TryParse(s, out var result)) { current.currentCooldown = result; } } } } [HarmonyPatch(typeof(FrontierDefeatScreen), "Open")] internal static class FrontierDefeatScreen_Open { [HarmonyPostfix] private static void Postfix(FrontierDefeatScreen __instance) { TimeMachineMod.CreateTimelineUI(((Component)((GameMenu)__instance).commonPanel).gameObject, -50); } } [HarmonyPatch(typeof(StaminaTraitArtifact), "Initialise")] internal static class StaminaTraitArtifact_Initialise { [HarmonyPrefix] internal static void Prefix(StaminaTraitArtifact __instance, Model modelToUse) { StaminaTraitArtifactModel staminaTraitArtifactModel = default(StaminaTraitArtifactModel); if (Il2CppSystemObjectExt.Is((Il2CppObjectBase)(object)modelToUse, ref staminaTraitArtifactModel)) { __instance.staminaTraitArtifactModel = staminaTraitArtifactModel; } } } [HarmonyPatch(typeof(Simulation), "GetSaveMetaData")] internal static class Simulation_GetSaveMetaData { [HarmonyPostfix] internal static void Postfix(Simulation __instance, Dictionary metaData) { FrontierInstaInventory frontierInstaInventory = __instance.frontierInstaInventory; if (((frontierInstaInventory != null) ? frontierInstaInventory.instas : null) != null) { Enumerator enumerator = __instance.frontierInstaInventory.instas.GetEnumerator(); while (enumerator.MoveNext()) { FrontierInstaMonkey current = enumerator.Current; metaData["FrontierStamina_" + current.frontierId] = current.stamina.ToString(); } } } } [HarmonyPatch(typeof(Simulation), "SetSaveMetaData")] internal static class Simulation_SetSaveMetaData { [HarmonyPostfix] internal static void Postfix(Simulation __instance, Dictionary metaData) { FrontierInstaInventory frontierInstaInventory = __instance.frontierInstaInventory; if (((frontierInstaInventory != null) ? frontierInstaInventory.instas : null) == null) { return; } Enumerator enumerator = __instance.frontierInstaInventory.instas.GetEnumerator(); string s = default(string); while (enumerator.MoveNext()) { FrontierInstaMonkey current = enumerator.Current; if (metaData.TryGetValue("FrontierStamina_" + current.frontierId, ref s) && float.TryParse(s, out var result)) { current.stamina = result; } } } } [HarmonyPatch(typeof(FrontierTraitsPanel), "UpdateStamina")] internal static class FrontierTraitsPanel_UpdateStamina { [HarmonyPrefix] internal static bool Prefix(FrontierTraitsPanel __instance) { return __instance.insta != null; } } [HarmonyPatch(typeof(TowerManager), "CreateTower")] internal static class TowerManager_CreateTower { [HarmonyPrefix] internal static void Prefix(TowerSaveDataModel? loadingSaveData, ref int frontierId) { if (loadingSaveData != null && loadingSaveData.frontierId > -1) { frontierId = loadingSaveData.frontierId; } } } public class TimeMachineMod : BloonsTD6Mod { public static readonly ModSettingHotkey StepBackwardHotkey = new ModSettingHotkey((KeyCode)276, (HotkeyModifier)2) { description = "Hotkey to load the previous saved round of this match" }; public static readonly ModSettingHotkey StepForwardHotkey = new ModSettingHotkey((KeyCode)275, (HotkeyModifier)2) { description = "Hotkey to load the subsequent saved round of this match" }; public static readonly ModSettingButton OpenSavesFolder = new ModSettingButton((Action)delegate { Process.Start(new ProcessStartInfo { FileName = SavesFolder, UseShellExecute = true, Verb = "open" }); }) { buttonText = "Open" }; public static readonly ModSettingButton DeleteData; private static ModHelperOption? deleteOption; public const string SavesFolderName = "TimeMachineSaves"; internal static readonly JsonSerializerSettings Settings; public static string OldSavesFolder => Path.Combine(FileIOHelper.sandboxRoot, "TimeMachineSaves"); public static string SavesFolder => Path.Combine(((PlayerServiceComponent)Game.instance.playerService).configuration.playerDataRootPath, "TimeMachineSaves", ((Player)(object)Game.Player).Data.ownerID ?? ""); public static string CurrentTimeMachineID => InGame.instance.GameId.ToString(); public static void CalcSize(ModHelperOption? option = null) { if ((Object)(object)option != (Object)null) { deleteOption = option; } DirectoryInfo folder = new DirectoryInfo(SavesFolder); if (!folder.Exists || (Object)(object)deleteOption == (Object)null) { return; } Task.Run(() => folder.EnumerateFiles("*", SearchOption.AllDirectories).Sum((FileInfo info) => info.Length)).ContinueWith(delegate(Task task) { TaskScheduler.ScheduleTask((Action)delegate { if ((Object)(object)deleteOption != (Object)null) { ((Component)deleteOption.TopRow).GetComponentInChildren().SetText($"Storing {(double)task.Result / 1000000.0:N1} mb of data"); } }, (Func)null); }); } public static void ClearData() { try { Directory.Delete(SavesFolder, recursive: true); Directory.CreateDirectory(SavesFolder); } catch (Exception ex) { ModHelper.Warning((object)ex); } CalcSize(); } public override void OnMainMenu() { DirectoryInfo directoryInfo = new DirectoryInfo(SavesFolder); if (!directoryInfo.Exists && Directory.Exists(OldSavesFolder)) { directoryInfo.Parent.Create(); Directory.Move(OldSavesFolder, SavesFolder); } if (!directoryInfo.Exists || (Game.Player.OnlineData == null && !string.IsNullOrEmpty(((Player)(object)Game.Player).Data.ownerID))) { return; } IEnumerable first = IEnumerableExt.OfIl2CppType((IEnumerable)Il2CppSystemDictionaryExt.GetValues(((Player)(object)Game.Player).Data.AllSavedMaps).ToArray()); OnlineProfileModel onlineData = Game.Player.OnlineData; object obj; if (onlineData == null) { obj = null; } else { Dictionary contentBrowserData = onlineData.contentBrowserData; obj = ((contentBrowserData != null) ? IEnumerableExt.OfIl2CppType((IEnumerable)Il2CppSystemDictionaryExt.Values(contentBrowserData).SelectMany(delegate(ContentTypeSaveData data) { List saveData = data.saveData; return ((saveData != null) ? Il2CppGenericsExt.ToList(saveData) : null) ?? new List(); })) : null); } IEnumerable enumerable = (IEnumerable)obj; IEnumerable usedGameIds = from mapSave in first.Concat(enumerable ?? Array.Empty()) select JsonConvert.SerializeObject((Object)(object)mapSave.gameId); foreach (DirectoryInfo item in from directoryInfo2 in directoryInfo.GetDirectories().ToList() where !usedGameIds.Contains(directoryInfo2.Name) select directoryInfo2) { ModHelper.Msg((object)("Deleting Time Machine saves for game " + item.Name + " since it was removed from profile")); try { item.Delete(recursive: true); } catch (Exception ex) { ModHelper.Warning((object)ex); } } } public override void OnUpdate() { if ((!StepBackwardHotkey.JustPressed() && !StepForwardHotkey.JustPressed()) || (Object)(object)InGame.instance == (Object)null || InGame.Bridge == null) { return; } List rounds = GetRounds(); if (rounds.Any()) { int currentRound = InGame.Bridge.GetCurrentRound(); if (InGame.Bridge.AreRoundsActive() && StepBackwardHotkey.JustPressed() && !InGame.instance.IsApopalypse && InGame.Bridge.GetBossBloon() == null) { currentRound++; } int[] array = rounds.Where((int r) => r < currentRound).ToArray(); int[] array2 = rounds.Where((int r) => r > currentRound).ToArray(); if (StepBackwardHotkey.JustPressed() && ArrayExt.Any(array)) { LoadRound(array.Last()); } if (StepForwardHotkey.JustPressed() && ArrayExt.Any(array2)) { LoadRound(array2.First()); } } } internal static MapSaveDataModel? GetSaveModel(int highestCompletedRound) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Invalid comparison between Unknown and I4 //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Invalid comparison between Unknown and I4 bool flag = false; Simulation simulation = InGame.Bridge.Simulation; if ((int)simulation.model.subGameType == 16) { FrontierBossManager frontierBossManager = simulation.frontierBossManager; if (frontierBossManager != null && frontierBossManager.IsBossGame) { if ((int)simulation.frontierBossManager.frontierGameManagerModel.boss == 6) { return null; } flag = true; simulation.model.subGameType = (SubGameType)4; } } MapSaveDataModel result = InGame.instance.CreateCurrentMapSave(highestCompletedRound, InGame.instance.MapDataSaveId); if (flag) { simulation.model.subGameType = (SubGameType)16; } return result; } public static void SaveRound(int completedRound, int highestCompletedRound) { string text = FilePathFor(CurrentTimeMachineID, completedRound + 1); MapSaveDataModel saveModel = GetSaveModel(highestCompletedRound); if (saveModel == null) { return; } string s = JsonConvert.SerializeObject((Object)(object)saveModel, Settings); byte[] bytes = Encoding.UTF8.GetBytes(s); using MemoryStream memoryStream = new MemoryStream(bytes); using (ZLibStream zLibStream = new ZLibStream(memoryStream, CompressionMode.Compress)) { zLibStream.Write(bytes, 0, bytes.Length); } Directory.CreateDirectory(new FileInfo(text).DirectoryName); File.WriteAllBytes(text, memoryStream.ToArray()); } public static void LoadRound(int round) { if ((Object)(object)InGame.instance == (Object)null) { return; } string text = FilePathFor(CurrentTimeMachineID, round); string text2; if (File.Exists(text)) { byte[] buffer = File.ReadAllBytes(text); using MemoryStream stream = new MemoryStream(buffer); using MemoryStream memoryStream = new MemoryStream(); using (ZLibStream zLibStream = new ZLibStream(stream, CompressionMode.Decompress)) { zLibStream.CopyTo(memoryStream); } text2 = Encoding.UTF8.GetString(memoryStream.ToArray()); } else { if (!File.Exists(text + ".json")) { ModHelper.Warning((object)("No Time Machine data for " + text)); return; } text2 = File.ReadAllText(text + ".json"); } MapSaveDataModel saveModel = JsonConvert.DeserializeObject(text2, Settings); LoadSave(saveModel); } public static void LoadSave(MapSaveDataModel saveModel) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Invalid comparison between Unknown and I4 //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Invalid comparison between Unknown and I4 //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Expected O, but got Unknown //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Invalid comparison between Unknown and I4 //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Invalid comparison between Unknown and I4 ReadonlyInGameData currentGame = InGameData.CurrentGame; ChallengeType? obj; if (currentGame == null) { obj = null; } else { DailyChallengeModel dcModel = currentGame.dcModel; obj = ((dcModel != null) ? new ChallengeType?(dcModel.chalType) : ((ChallengeType?)null)); } ChallengeType? val = obj; bool flag; if (val.HasValue) { ChallengeType valueOrDefault = val.GetValueOrDefault(); if ((int)valueOrDefault == 3 || (int)valueOrDefault == 12) { flag = true; goto IL_005a; } } flag = false; goto IL_005a; IL_005a: if (flag && saveModel.gameVersion != ((Object)Game.Version).ToString()) { PopupScreenExt.SafelyQueue(PopupScreen.instance, (Action)delegate(PopupScreen screen) { screen.ShowOkPopup("Can't load save from an older BTD6 version for a Custom Map", (ReturnCallback)null); }); return; } InGame.Bridge.ExecuteContinueFromCheckpoint(InGame.Bridge.MyPlayerNumber, new KonFuze(0.0), ref saveModel, true, false); ArtifactManager artifactManager = InGame.Bridge.Simulation.artifactManager; GameType gameType = InGame.instance.GameType; GameType val2 = gameType; if ((int)val2 != 13) { if ((int)val2 == 14) { ShopMenuExt.instance.RebuildFrontierTowers(); foreach (ArtifactLoot item in (Il2CppArrayBase)(object)InGameData.CurrentGame.frontierIngameData.equippedArtifacts) { artifactManager.Activate(item.artifactName, item.frontierIds); } } } else { ShopMenuExt.instance.RebuildRogueTowers(); foreach (ArtifactLoot item2 in (Il2CppArrayBase)(object)InGameData.CurrentGame.rogueData.equippedArtifacts) { if (!artifactManager.IsArtifactActive(item2.artifactName)) { artifactManager.Activate(item2.artifactName, (List)null); } } } ((Player)(object)Game.Player).Data.SetSavedMap(saveModel.savedMapsId, saveModel); } public static string FilePathFor(string gameId, int round) { return Path.Combine(SavesFolder, gameId, round.ToString()); } public static List GetRounds() { DirectoryInfo directoryInfo = new DirectoryInfo(Path.Combine(SavesFolder, CurrentTimeMachineID)); if (!directoryInfo.Exists) { return new List(); } int result; return (from fileInfo in directoryInfo.GetFiles() select int.TryParse(Path.GetFileNameWithoutExtension(fileInfo.Name), out result) ? result : 0 into i where i != 0 orderby i select i).ToList(); } public static void CreateTimelineUI(GameObject mainPanel, int yOffset = 0) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) DirectoryInfo directoryInfo = new DirectoryInfo(Path.Combine(SavesFolder, CurrentTimeMachineID)); if (!directoryInfo.Exists) { return; } List rounds = GetRounds(); if (!rounds.Any()) { return; } ModHelperScrollPanel val = GameObjectExt.AddModHelperScrollPanel(mainPanel, new Info("TimeMachineScroll", 0f, (float)(-1150 + yOffset), 2500f, 150f), (Axis?)(Axis)0, "Ui[MainBgPanelHematite]", 100f, 0); GameObjectExt.AddModHelperComponent(mainPanel, ModHelperImage.Create(new Info("TimeIcon", -1400f, (float)(-1150 + yOffset), 175f), "Ui[StopWatch]")); GameObjectExt.AddModHelperComponent(mainPanel, ModHelperImage.Create(new Info("TimeIcon2", 1400f, (float)(-1150 + yOffset), 200f), "PowerIcons[DartTimeIcon]")); int currentRound = InGame.instance.bridge.GetCurrentRound(); foreach (int round in rounds) { string message = $"Travel back {((round > currentRound) ? "(to the future!)" : "to")} when you finished round {round}?\nRound {round + 1} will be about to start."; string text = ((round == currentRound) ? "Ui[YellowBtn]" : "Ui[BrightBlueBtn]"); ModHelperButton val2 = ((ModHelperComponent)val.ScrollContent).AddButton(new Info($"Btn{round}", 140f), text, Action.op_Implicit((Action)delegate { AudioClipExtensions.Play(MenuManager.instance.buttonClick3Sound, "ClickSounds", 1f); PopupScreenExt.SafelyQueue(PopupScreen.instance, (Action)delegate(PopupScreen screen) { screen.ShowPopup((Placement)2, "Time Machine", message, ReturnCallback.op_Implicit((Action)delegate { LoadRound(round); }), "Yes", (ReturnCallback)null, "No", (TransitionAnim)1, (BackGround)0, false, false); }); })); Info val3 = new Info("Text", (InfoPreset)0); ((Info)(ref val3)).set_Width(50f); ((ModHelperComponent)val2).AddText(val3, round.ToString(), 100f); } float value = (float)InGame.instance.bridge.GetCurrentRound() / (float)rounds.Max(); val.ScrollRect.horizontalNormalizedPosition = Math.Clamp(value, 0f, 1f); } static TimeMachineMod() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //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_005b: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown //IL_00aa: 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_00bc: Expected O, but got Unknown ModSettingButton val = new ModSettingButton((Action)delegate { PopupScreen.instance.ShowPopup((Placement)2, "Delete Data", "Are you sure you want to delete all Time Machine Backups?", ReturnCallback.op_Implicit((Action)ClearData), "Delete", (ReturnCallback)null, "Cancel", (TransitionAnim)1, (BackGround)1, false, false); }); ((ModSetting)val).displayName = "Calculating..."; val.buttonText = "Delete Data"; val.buttonSprite = "Ui[RedBtnLong]"; ((ModSetting)val).modifyOption = CalcSize; DeleteData = val; Settings = new JsonSerializerSettings { TypeNameHandling = (TypeNameHandling)1 }; } } }