Some mods may be broken due to the recent Alloyed Collective update.
Decompiled source of RetryButton v1.0.2
plugins/RespawnButton/RespawnButton.dll
Decompiled a year 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; } } } }