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 RetryButton v1.0.2
plugins/RespawnButton/RespawnButton.dll
Decompiled 2 years agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq.Expressions; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Logging; using HG.Reflection; using IL.RoR2; using Microsoft.CodeAnalysis; using Mono.Cecil.Cil; using MonoMod.Cil; using MonoMod.RuntimeDetour; using On.RoR2.UI; using ProperSave; using R2API.Utils; using RespawnButton.Patches; using RoR2; using RoR2.UI; using UnityEngine; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: NetworkCompatibility(/*Could not decode attribute arguments.*/)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("RespawnButton")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+3e165d11156c273bc297d51c54dc96fcccb18dcf")] [assembly: AssemblyProduct("RespawnButton")] [assembly: AssemblyTitle("RespawnButton")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [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; } } } namespace RespawnButton { internal static class LanguageFolderHandler { public static void Register(string searchFolder, string langFolderName = "lang") { string langFolderPath = Path.Combine(searchFolder, langFolderName); if (Directory.Exists(langFolderPath)) { Language.collectLanguageRootFolders += delegate(List<string> folders) { folders.Add(langFolderPath); }; } } } internal static class Log { private static readonly StringBuilder _sharedStringBuilder; private static readonly int _cachedCallerPathPrefixLength; private static ManualLogSource _logSource; static Log() { _sharedStringBuilder = new StringBuilder(256); _cachedCallerPathPrefixLength = getCallerPathPrefixLength("X:\\Git\\RoR2\\RespawnButton\\RespawnButton\\Log.cs"); static int getCallerPathPrefixLength([CallerFilePath] string callerPath = null) { int num = callerPath.LastIndexOf("RespawnButton\\"); if (num >= 0) { return num + "RespawnButton\\".Length; } Debug.LogError((object)"[RespawnButton] Logger failed to determine caller path prefix length"); return 0; } } internal static void Init(ManualLogSource logSource) { _logSource = logSource; } private static StringBuilder AppendCallerPrefix(this StringBuilder stringBuilder, string callerPath, string callerMemberName, int callerLineNumber) { return stringBuilder.Append(callerPath, _cachedCallerPathPrefixLength, callerPath.Length - _cachedCallerPathPrefixLength).Append(':').Append(callerLineNumber) .Append(" (") .Append(callerMemberName) .Append("):"); } private static StringBuilder buildCallerLogString(string callerPath, string callerMemberName, int callerLineNumber, object data) { return _sharedStringBuilder.Clear().AppendCallerPrefix(callerPath, callerMemberName, callerLineNumber).Append(' ') .Append(data); } internal static void Error(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogError((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void Error_NoCallerPrefix(object data) { _logSource.LogError(data); } internal static void Fatal(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogFatal((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void Fatal_NoCallerPrefix(object data) { _logSource.LogFatal(data); } internal static void Info(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogInfo((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void Info_NoCallerPrefix(object data) { _logSource.LogInfo(data); } internal static void Message(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogMessage((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void Message_NoCallerPrefix(object data) { _logSource.LogMessage(data); } internal static void Warning(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogWarning((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void Warning_NoCallerPrefix(object data) { _logSource.LogWarning(data); } } public class RespawnButtonController : MonoBehaviour { private Transform _respawnButtonInstance; private GameEndReportPanelController _gameEndPanelController; public bool IsVisible { get { if (Object.op_Implicit((Object)(object)_respawnButtonInstance)) { return ((Component)_respawnButtonInstance).gameObject.activeSelf; } return false; } set { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown if (IsVisible == value) { return; } if (!Object.op_Implicit((Object)(object)_respawnButtonInstance)) { if (!value) { return; } MPButton continueButton = _gameEndPanelController.continueButton; if (Object.op_Implicit((Object)(object)continueButton)) { GameObject val = Object.Instantiate<GameObject>(((Component)continueButton).gameObject, ((Component)continueButton).transform.parent); val.transform.SetAsLastSibling(); ((Object)val).name = "RespawnButton"; HGButton component = val.GetComponent<HGButton>(); ((UnityEventBase)((Button)component).onClick).RemoveAllListeners(); ((UnityEvent)((Button)component).onClick).AddListener(new UnityAction(onRespawnClicked)); ((Selectable)component).interactable = shouldBeInteractable(); LanguageTextMeshController componentInChildren = val.GetComponentInChildren<LanguageTextMeshController>(); if (Object.op_Implicit((Object)(object)componentInChildren)) { componentInChildren.token = "GAME_REPORT_SCREEN_RESPAWN_BUTTON_LABEL"; } Transform val2 = val.transform.Find("GenericGlyph"); if (Object.op_Implicit((Object)(object)val2)) { ((Component)val2).gameObject.SetActive(false); } _respawnButtonInstance = val.transform; } } else { ((Component)_respawnButtonInstance).gameObject.SetActive(value); } } } private static bool shouldShowOnReportScreen(RunReport runReport) { if (!NetworkServer.dontListen) { Run instance = Run.instance; if (instance is EclipseRun || instance is WeeklyRun) { return false; } } if (runReport == null) { return false; } if (!Object.op_Implicit((Object)(object)runReport.gameEnding) || runReport.gameEnding.isWin) { return false; } return true; } private static bool shouldBeInteractable() { return Loading.CurrentSave != null; } private void Awake() { _gameEndPanelController = ((Component)this).GetComponent<GameEndReportPanelController>(); } public void OnSetDisplayData(DisplayData newDisplayData) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) IsVisible = NetworkServer.active && shouldShowOnReportScreen(newDisplayData.runReport); } private void onRespawnClicked() { if (!Object.op_Implicit((Object)(object)Run.instance)) { return; } SceneDef currentRunScene = SceneCatalog.mostRecentSceneDef; ProperSave_SaveFileDeletionHook.SuppressSaveFileDeletion = true; OverridePostRunDestinationPatch.OverridePostRunDestinationDelegate oldPostRunDestinationOverride = OverridePostRunDestinationPatch.PostRunDestinationOverride; OverridePostRunDestinationPatch.PostRunDestinationOverride = delegate { if (NetworkServer.active) { NetworkManager.singleton.ServerChangeScene("lobby"); } }; try { NetworkSession.instance.EndRun(); } finally { ((MonoBehaviour)RoR2Application.instance).StartCoroutine(waitThenDisableSaveSuppression()); } ((MonoBehaviour)RoR2Application.instance).StartCoroutine(waitForLobbyLoadThenLoadSave()); IEnumerator waitForLobbyLoadThenLoadSave() { SceneDef characterSelectScene = SceneCatalog.FindSceneDef("lobby"); while ((Object)(object)SceneCatalog.mostRecentSceneDef != (Object)(object)characterSelectScene) { if ((Object)(object)SceneCatalog.mostRecentSceneDef != (Object)(object)currentRunScene) { Log.Info("Unexpected exit scene, run exited to " + SceneCatalog.mostRecentSceneDef.cachedName + ", expected " + characterSelectScene.cachedName + ". Aborting restart.", "X:\\Git\\RoR2\\RespawnButton\\RespawnButton\\RespawnButtonController.cs", "onRespawnClicked", 159); yield break; } yield return 0; } yield return (object)new WaitUntil((Func<bool>)NetworkUser.AllParticipatingNetworkUsersReady); yield return (object)new WaitForEndOfFrame(); yield return Loading.LoadLobby(); } IEnumerator waitThenDisableSaveSuppression() { yield return (object)new WaitForEndOfFrame(); ProperSave_SaveFileDeletionHook.SuppressSaveFileDeletion = false; OverridePostRunDestinationPatch.PostRunDestinationOverride = oldPostRunDestinationOverride; } } } [BepInPlugin("Gorakh.RespawnButton", "RespawnButton", "1.0.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class RespawnButtonPlugin : BaseUnityPlugin { [CompilerGenerated] private static class <>O { public static hook_Awake <0>__GameEndReportPanelController_Awake; public static hook_SetDisplayData <1>__GameEndReportPanelController_SetDisplayData; } public const string PluginGUID = "Gorakh.RespawnButton"; public const string PluginAuthor = "Gorakh"; public const string PluginName = "RespawnButton"; public const string PluginVersion = "1.0.2"; internal static RespawnButtonPlugin Instance { get; private set; } private void Awake() { //IL_004b: 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_0056: Expected O, but got Unknown //IL_006b: 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) //IL_0076: Expected O, but got Unknown Stopwatch stopwatch = Stopwatch.StartNew(); Log.Init(((BaseUnityPlugin)this).Logger); Instance = SingletonHelper.Assign<RespawnButtonPlugin>(Instance, this); LanguageFolderHandler.Register(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location)); object obj = <>O.<0>__GameEndReportPanelController_Awake; if (obj == null) { hook_Awake val = GameEndReportPanelController_Awake; <>O.<0>__GameEndReportPanelController_Awake = val; obj = (object)val; } GameEndReportPanelController.Awake += (hook_Awake)obj; object obj2 = <>O.<1>__GameEndReportPanelController_SetDisplayData; if (obj2 == null) { hook_SetDisplayData val2 = GameEndReportPanelController_SetDisplayData; <>O.<1>__GameEndReportPanelController_SetDisplayData = val2; obj2 = (object)val2; } GameEndReportPanelController.SetDisplayData += (hook_SetDisplayData)obj2; stopwatch.Stop(); Log.Info_NoCallerPrefix($"Initialized in {stopwatch.Elapsed.TotalSeconds:F2} seconds"); } private void OnDestroy() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown object obj = <>O.<0>__GameEndReportPanelController_Awake; if (obj == null) { hook_Awake val = GameEndReportPanelController_Awake; <>O.<0>__GameEndReportPanelController_Awake = val; obj = (object)val; } GameEndReportPanelController.Awake -= (hook_Awake)obj; object obj2 = <>O.<1>__GameEndReportPanelController_SetDisplayData; if (obj2 == null) { hook_SetDisplayData val2 = GameEndReportPanelController_SetDisplayData; <>O.<1>__GameEndReportPanelController_SetDisplayData = val2; obj2 = (object)val2; } GameEndReportPanelController.SetDisplayData -= (hook_SetDisplayData)obj2; Instance = SingletonHelper.Unassign<RespawnButtonPlugin>(Instance, this); } private static void GameEndReportPanelController_Awake(orig_Awake orig, GameEndReportPanelController self) { orig.Invoke(self); ((Component)self).gameObject.AddComponent<RespawnButtonController>(); } private static void GameEndReportPanelController_SetDisplayData(orig_SetDisplayData orig, GameEndReportPanelController self, DisplayData newDisplayData) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) orig.Invoke(self, newDisplayData); RespawnButtonController respawnButtonController = default(RespawnButtonController); if (((Component)self).TryGetComponent<RespawnButtonController>(ref respawnButtonController)) { respawnButtonController.OnSetDisplayData(newDisplayData); } } } } namespace RespawnButton.Patches { internal static class OverridePostRunDestinationPatch { public delegate void OverridePostRunDestinationDelegate(Run run); [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func<Instruction, bool> <>9__2_1; public static Func<Run, bool> <>9__2_2; public static Manipulator <>9__2_0; internal void <Init>b__2_0(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_004e: 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) ILCursor val = new ILCursor(il); if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<Run>(x, "HandlePostRunDestination") })) { ILLabel val2 = val.MarkLabel(); val.Index -= 2; val.Emit(OpCodes.Ldarg_0); val.EmitDelegate<Func<Run, bool>>((Func<Run, bool>)delegate(Run run) { if (PostRunDestinationOverride == null) { return true; } PostRunDestinationOverride(run); return false; }); val.Emit(OpCodes.Brfalse, (object)val2); } else { Log.Error("Failed to find patch location", "X:\\Git\\RoR2\\RespawnButton\\RespawnButton\\Patches\\OverridePostRunDestinationPatch.cs", "Init", 42); } } internal bool <Init>b__2_1(Instruction x) { return ILPatternMatchingExt.MatchCallOrCallvirt<Run>(x, "HandlePostRunDestination"); } internal bool <Init>b__2_2(Run run) { if (PostRunDestinationOverride == null) { return true; } PostRunDestinationOverride(run); return false; } } public static OverridePostRunDestinationDelegate PostRunDestinationOverride; [SystemInitializer(new Type[] { })] private static void Init() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown object obj = <>c.<>9__2_0; if (obj == null) { Manipulator val = delegate(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_004e: 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) ILCursor val2 = new ILCursor(il); if (val2.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<Run>(x, "HandlePostRunDestination") })) { ILLabel val3 = val2.MarkLabel(); val2.Index -= 2; val2.Emit(OpCodes.Ldarg_0); val2.EmitDelegate<Func<Run, bool>>((Func<Run, bool>)delegate(Run run) { if (PostRunDestinationOverride == null) { return true; } PostRunDestinationOverride(run); return false; }); val2.Emit(OpCodes.Brfalse, (object)val3); } else { Log.Error("Failed to find patch location", "X:\\Git\\RoR2\\RespawnButton\\RespawnButton\\Patches\\OverridePostRunDestinationPatch.cs", "Init", 42); } }; <>c.<>9__2_0 = val; obj = (object)val; } Run.OnDestroy += (Manipulator)obj; } } internal static class ProperSave_SaveFileDeletionHook { private delegate void orig_Saving_RunOnServerGameOver(Run run, GameEndingDef ending); private static orig_Saving_RunOnServerGameOver _origRunOnServerGameOver; public static bool SuppressSaveFileDeletion; private static bool _deleteSaveFileOnRunEnd; private static Run _lastRunInstance; private static GameEndingDef _lastGameEndingDef; [SystemInitializer(new Type[] { })] private static void Init() { //IL_0066: Unknown result type (might be due to invalid IL or missing references) _origRunOnServerGameOver = new Hook((Expression<Action>)(() => Saving.RunOnServerGameOver((Run)null, (GameEndingDef)null)), (Delegate)new Action<orig_Saving_RunOnServerGameOver, Run, GameEndingDef>(Saving_RunOnServerGameOver)).GenerateTrampoline<orig_Saving_RunOnServerGameOver>(); Run.onRunDestroyGlobal += Run_onRunDestroyGlobal; } private static void Saving_RunOnServerGameOver(orig_Saving_RunOnServerGameOver orig, Run run, GameEndingDef ending) { if (ending.isWin) { orig(run, ending); return; } _deleteSaveFileOnRunEnd = true; _lastRunInstance = run; _lastGameEndingDef = ending; } private static void deleteSaveFile() { _origRunOnServerGameOver(_lastRunInstance, _lastGameEndingDef); } private static void Run_onRunDestroyGlobal(Run _) { if (!_deleteSaveFileOnRunEnd) { return; } try { if (NetworkServer.active && !SuppressSaveFileDeletion) { deleteSaveFile(); } } finally { _deleteSaveFileOnRunEnd = false; _lastRunInstance = null; _lastGameEndingDef = null; } } } }