using System;
using System.Collections;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("UndoEverywhere")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0+2cd7dffe237c43664f261c2e9e93d030f595de9b")]
[assembly: AssemblyProduct("UndoEverywhere")]
[assembly: AssemblyTitle("UndoEverywhere")]
[assembly: AssemblyVersion("0.1.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.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = 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 UndoEverywhere
{
[BepInPlugin("UndoEverywhere", "UndoEverywhere", "0.1.0")]
public class Plugin : BaseUnityPlugin
{
private class CoroutineRunner : MonoBehaviour
{
}
internal static ManualLogSource Logger = new ManualLogSource("UndoEverywhere");
private static CoroutineRunner? coroutineRunner;
public void Awake()
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
Logger = ((BaseUnityPlugin)this).Logger;
Logger.LogInfo((object)"Plugin UndoEverywhere is loaded!");
new Harmony("UndoEverywhere").PatchAll();
}
internal static Coroutine RunCoroutine(IEnumerator routine)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Expected O, but got Unknown
if ((Object)(object)coroutineRunner == (Object)null)
{
GameObject val = new GameObject("CoroutineRunner");
Object.DontDestroyOnLoad((Object)val);
coroutineRunner = val.AddComponent<CoroutineRunner>();
}
return ((MonoBehaviour)coroutineRunner).StartCoroutine(routine);
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "UndoEverywhere";
public const string PLUGIN_NAME = "UndoEverywhere";
public const string PLUGIN_VERSION = "0.1.0";
}
}
namespace UndoEverywhere.Patches
{
[HarmonyPatch(typeof(PauseDialog), "ShouldShowRestartBattleButton")]
internal static class PauseDialog_RestartOutsideBattle_Patch
{
private static void Postfix(SaveManager ___saveManager, ref bool __result)
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
if (!__result && !((Object)(object)___saveManager == (Object)null) && StageStartMarker.HasCheckpoint(___saveManager) && StageStartMarker.IsRestartableState(___saveManager.GetGameSequence()))
{
__result = true;
}
}
}
[HarmonyPatch(typeof(PauseDialog), "RefreshRestartBattleButton")]
internal static class PauseDialog_RestartLabel_Patch
{
private static string? vanillaText;
private static void Postfix(SaveManager ___saveManager, TMP_Text ___restartBattleNormalLabel)
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
if (vanillaText == null)
{
vanillaText = ___restartBattleNormalLabel.text;
}
bool flag = (Object)(object)___saveManager != (Object)null && !___saveManager.IsInBattle() && StageStartMarker.HasCheckpoint(___saveManager) && StageStartMarker.IsRestartableState(___saveManager.GetGameSequence());
___restartBattleNormalLabel.text = (flag ? "Restart Ring" : vanillaText);
}
}
[HarmonyPatch(typeof(SaveManager), "RestartBattle")]
internal static class SaveManager_RestartStage_Patch
{
private static bool Prefix(SaveManager __instance)
{
if (__instance.IsInBattle())
{
return true;
}
if (!StageStartMarker.TryGetCheckpointJson(__instance, out string json))
{
Plugin.Logger.LogWarning((object)"[SaveManager_RestartStage_Patch] no stage-start checkpoint set, aborting restart");
return false;
}
try
{
Plugin.RunCoroutine(RestartStageCoroutine(__instance, json));
}
catch (Exception arg)
{
Plugin.Logger.LogError((object)$"[SaveManager_RestartStage_Patch] exception starting coroutine: {arg}");
}
return false;
}
private static IEnumerator RestartStageCoroutine(SaveManager saveManager, string checkpointJson)
{
try
{
JsonUtility.FromJsonOverwrite(checkpointJson, StageStartMarker.GetActiveSaveData(saveManager));
}
catch (Exception arg)
{
Plugin.Logger.LogError((object)$"[SaveManager_RestartStage_Patch] exception restoring checkpoint: {arg}");
yield break;
}
GameStateManager gameStateManager = AllGameManagers.Instance.GetGameStateManager();
ScreenManager screenManager = AllGameManagers.Instance.GetScreenManager();
RunType runType = saveManager.GetRunType();
string sharecode = saveManager.GetShareCode();
gameStateManager.LeaveGame();
screenManager.ReturnToMainMenu();
yield return (object)new WaitUntil((Func<bool>)(() => screenManager.GetScreenActive((ScreenName)15)));
yield return null;
yield return null;
yield return null;
bool runLoaded = false;
gameStateManager.ContinueRun(runType, sharecode, (Action)delegate
{
runLoaded = true;
});
yield return (object)new WaitUntil((Func<bool>)(() => runLoaded));
}
}
internal static class StageStartMarker
{
private static readonly PropertyInfo ActiveSaveDataProperty = AccessTools.Property(typeof(SaveManager), "ActiveSaveData");
private static string CheckpointPath(SaveManager saveManager)
{
return saveManager.ActiveSavePath + ".stagestart";
}
internal static object GetActiveSaveData(SaveManager saveManager)
{
return ActiveSaveDataProperty.GetValue(saveManager);
}
internal static void CaptureCurrent(SaveManager saveManager)
{
try
{
string contents = JsonUtility.ToJson(GetActiveSaveData(saveManager));
File.WriteAllText(CheckpointPath(saveManager), contents);
}
catch (Exception arg)
{
Plugin.Logger.LogError((object)$"[StageStartMarker] failed to capture checkpoint: {arg}");
}
}
internal static bool HasCheckpoint(SaveManager saveManager)
{
return File.Exists(CheckpointPath(saveManager));
}
internal static bool TryGetCheckpointJson(SaveManager saveManager, out string json)
{
string path = CheckpointPath(saveManager);
if (!File.Exists(path))
{
json = string.Empty;
return false;
}
json = File.ReadAllText(path);
return true;
}
internal static bool IsRestartableState(GameSequence sequence)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0002: Invalid comparison between Unknown and I4
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Invalid comparison between Unknown and I4
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Invalid comparison between Unknown and I4
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Invalid comparison between Unknown and I4
if ((int)sequence != 1 && (int)sequence != 6 && (int)sequence != 4)
{
return (int)sequence > 0;
}
return false;
}
}
[HarmonyPatch(typeof(GameStateManager), "StartNewRun")]
internal static class GameStateManager_StageStartMarker_Patch
{
private static void Postfix()
{
AllGameManagers instance = AllGameManagers.Instance;
SaveManager val = ((instance != null) ? instance.GetSaveManager() : null);
if ((Object)(object)val != (Object)null)
{
StageStartMarker.CaptureCurrent(val);
}
}
}
[HarmonyPatch(typeof(GameScreen), "ShowScreenAfterBattle")]
internal static class GameScreen_StageStartMarker_Patch
{
private static void Postfix(SaveManager ___saveManager)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Invalid comparison between Unknown and I4
if ((int)___saveManager.GetGameSequence() != 4)
{
StageStartMarker.CaptureCurrent(___saveManager);
}
}
}
}