using 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;
}
}
}
}