using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using UnityEngine; using UnityEngine.Events; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("JustRetryPlus")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.3.0")] [assembly: AssemblyInformationalVersion("1.0.3")] [assembly: AssemblyProduct("JustRetryPlus")] [assembly: AssemblyTitle("JustRetryPlus")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.3.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [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 JustRetryPlus { [HarmonyPatch(typeof(RunManager), "ChangeLevel")] public static class ChangeLevelPatch { private static bool Prefix(RunManager __instance, ref bool _completedLevel, ref bool _levelFailed, ref ChangeLevelType _changeLevelType) { if (!Plugin.IsEnabled) { return true; } if (Plugin.WaitingForRetryChoice) { return false; } Plugin.Logger.LogInfo((object)$"Level failed?: {_levelFailed}"); Plugin.DidFailLevel = _levelFailed; if (Plugin.DidFailLevel) { Plugin.Logger.LogInfo((object)"Level failed, showing retry popup..."); Plugin.Instance.ShowNativeRetryMenu(); return false; } return true; } } public class HealRunner : MonoBehaviour { } public static class MyPluginInfo { public const string PLUGIN_GUID = "JustRetryPlus"; public const string PLUGIN_NAME = "JustRetryPlus"; public const string PLUGIN_VERSION = "1.0.3"; } [BepInPlugin("JustRetryPlus", "JustRetryPlus", "1.0.3")] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Logger; private static ConfigEntry _shouldResetLevel; private static ConfigEntry _shouldHealAfterFail; private static ConfigEntry _isEnabled; private static ConfigEntry _healthToHeal; public static Plugin Instance; public static bool ShouldResetLevel => _shouldResetLevel.Value; public static bool ShouldHealAfterFail => _shouldHealAfterFail.Value; public static bool DidFailLevel { get; set; } public static bool WaitingForRetryChoice { get; set; } public static bool IsEnabled => _isEnabled.Value; public static int HealthToHealValue => _healthToHeal.Value; private void Awake() { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Expected O, but got Unknown //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Expected O, but got Unknown //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Expected O, but got Unknown //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Expected O, but got Unknown //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Expected O, but got Unknown //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Expected O, but got Unknown Instance = this; Logger = ((BaseUnityPlugin)this).Logger; Logger.LogInfo((object)"Plugin JustRetryPlus is loaded!"); Logger.LogInfo((object)"Thanks for nickklmao for the original Idea and bits of code! please check out their mods on Thunderstore!"); Logger.LogInfo((object)"Without them this mod wouldn't be possible!"); Harmony val = new Harmony("eu.xaru.justretryplus"); val.PatchAll(); Logger.LogInfo((object)"Harmony patches applied."); _isEnabled = ((BaseUnityPlugin)this).Config.Bind("Settings", "IsEnabled", true, new ConfigDescription("Toggle if the plugin should be enabled, if false the normal game death scene will take over", (AcceptableValueBase)new AcceptableValueRange(false, true), Array.Empty())); _shouldResetLevel = ((BaseUnityPlugin)this).Config.Bind("Settings", "ShouldResetLevel", false, new ConfigDescription("Toggle if the game should restart at level one & reset the map when failing a level", (AcceptableValueBase)new AcceptableValueRange(false, true), Array.Empty())); _shouldHealAfterFail = ((BaseUnityPlugin)this).Config.Bind("Settings", "ShouldHealAfterFail", true, new ConfigDescription("Toggle if the game should restart with full health when failing a level", (AcceptableValueBase)new AcceptableValueRange(false, true), Array.Empty())); _healthToHeal = ((BaseUnityPlugin)this).Config.Bind("Settings", "HealthToHeal", 100, new ConfigDescription("The amount of health to heal when failing a level", (AcceptableValueBase)new AcceptableValueRange(0, 500), Array.Empty())); } private void Start() { Logger.LogInfo((object)"JustRetryPlus started!"); } public static IEnumerator HandleRestartHeal(MonoBehaviour runner) { GameDirector oldDirector = GameDirector.instance; while ((Object)(object)GameDirector.instance == (Object)(object)oldDirector && (Object)(object)oldDirector != (Object)null) { yield return (object)new WaitForSeconds(0.1f); } while ((Object)(object)GameDirector.instance == (Object)null || (Object)(object)LevelGenerator.Instance == (Object)null) { yield return (object)new WaitForSeconds(0.5f); } while (!LevelGenerator.Instance.Generated) { yield return (object)new WaitForSeconds(0.5f); } while (GameDirector.instance.PlayerList == null || GameDirector.instance.PlayerList.Count < PhotonNetwork.PlayerList.Length) { yield return (object)new WaitForSeconds(0.5f); } yield return (object)new WaitForSeconds(1.5f); int healAmount = HealthToHealValue; foreach (PlayerAvatar player in SemiFunc.PlayerGetAll()) { if ((Object)(object)player != (Object)null && (Object)(object)player.playerHealth != (Object)null) { string steamID = SemiFunc.PlayerGetSteamID(player); if ((Object)(object)StatsManager.instance != (Object)null) { StatsManager.instance.SetPlayerHealth(steamID, healAmount, false); } int maxHealth = (int)AccessTools.Field(typeof(PlayerHealth), "maxHealth").GetValue(player.playerHealth); healAmount = Mathf.Clamp(healAmount, 0, maxHealth); AccessTools.Field(typeof(PlayerHealth), "health").SetValue(player.playerHealth, healAmount); PhotonView photonView = ((Component)player.playerHealth).GetComponent(); if ((Object)(object)photonView != (Object)null) { photonView.RPC("UpdateHealthRPC", (RpcTarget)0, new object[4] { healAmount, maxHealth, true, false }); } Logger.LogInfo((object)$"[JustRetryPlus] Successfully healed {steamID} to {healAmount} HP."); } } if ((Object)(object)StatsManager.instance != (Object)null) { if (StatsManager.instance.runStats.ContainsKey("chargingStationChargeTotal")) { StatsManager.instance.runStats["chargingStationCharge"] = StatsManager.instance.runStats["chargingStationChargeTotal"]; } else { StatsManager.instance.runStats["chargingStationCharge"] = 100; } List keys = new List(StatsManager.instance.itemStatBattery.Keys); foreach (string key in keys) { StatsManager.instance.itemStatBattery[key] = 100; } } if ((Object)(object)runner != (Object)null && (Object)(object)((Component)runner).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)runner).gameObject); } } public void ShowNativeRetryMenu() { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Expected O, but got Unknown //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Expected O, but got Unknown //IL_00f2: Unknown result type (might be due to invalid IL or missing references) if (WaitingForRetryChoice) { return; } WaitingForRetryChoice = true; if ((Object)(object)MenuManager.instance == (Object)null) { Logger.LogWarning((object)"MenuManager.instance is null! Falling back to instant retry."); ExecuteRetry(); return; } try { Cursor.visible = true; Cursor.lockState = (CursorLockMode)0; MenuManager.instance.SetState(0); MenuManager.instance.PageOpen((MenuPageIndex)1, false); GameObject dummyObj = new GameObject("JustRetryPlus_PopUpDummy"); Object.DontDestroyOnLoad((Object)(object)dummyObj); MenuButtonPopUp val = dummyObj.AddComponent(); val.option1Event = new UnityEvent(); val.option1Event.AddListener((UnityAction)delegate { Object.Destroy((Object)(object)dummyObj); ExecuteRetry(); }); val.option2Event = new UnityEvent(); val.option2Event.AddListener((UnityAction)delegate { Object.Destroy((Object)(object)dummyObj); ExecuteLobby(); }); MenuManager.instance.PagePopUpTwoOptions(val, "Mission Failed", (LocalizedAsset)null, Color.red, "Your crew has failed. Would you like to retry the level?", (LocalizedAsset)null, "Retry Level", (LocalizedAsset)null, "Back to Lobby", (LocalizedAsset)null, false); } catch (Exception arg) { Logger.LogError((object)$"Exception showing native retry menu: {arg}"); Logger.LogWarning((object)"Falling back to instant retry due to error."); ExecuteRetry(); } } public void ExecuteRetry() { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown WaitingForRetryChoice = false; if (ShouldResetLevel) { Logger.LogInfo((object)"Restarting at level one"); RunManager.instance.ResetProgress(); RunManager.instance.SetRunLevel(); } else if (ShouldHealAfterFail) { Logger.LogInfo((object)"Preparing to heal after retry..."); GameObject val = new GameObject("JustRetryPlus_HealRunner"); Object.DontDestroyOnLoad((Object)(object)val); HealRunner healRunner = val.AddComponent(); ((MonoBehaviour)healRunner).StartCoroutine(HandleRestartHeal((MonoBehaviour)(object)healRunner)); } Logger.LogInfo((object)"Level failed, retrying..."); RunManager.instance.RestartScene(); Logger.LogInfo((object)"Restarted scene"); } public void ExecuteLobby() { WaitingForRetryChoice = false; Logger.LogInfo((object)"Returning to lobby..."); RunManager.instance.ChangeLevel(false, false, (ChangeLevelType)3); } } public static class PluginInfo { public const string PLUGIN_GUID = "JustRetryPlus"; public const string PLUGIN_NAME = "JustRetryPlus"; public const string PLUGIN_VERSION = "1.0.3"; } }