The BepInEx console will not appear when launching like it does for other games on Thunderstore. This is normal (and helps prevent crashes during startup). You can turn it back on in your BepInEx.cfg file.
Decompiled source of ReviveHotkey v1.0.8
BepInEx/plugins/ReviveHotkey.dll
Decompiled 4 days agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using Photon.Pun; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("ReviveHotkey")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ReviveHotkey")] [assembly: AssemblyTitle("ReviveHotkey")] [assembly: AssemblyVersion("1.0.0.0")] [BepInPlugin("com.revivehotkey", "ReviveHotkey", "1.0.7")] public class ReviveHotkey : BaseUnityPlugin { [CompilerGenerated] private sealed class <WaitForHUDAndCreatePrompt>d__15 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ReviveHotkey <>4__this; private GameObject <hud>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForHUDAndCreatePrompt>d__15(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <hud>5__1 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; ((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)"[ReviveHotkey] Searching for Canvas_HUD..."); <hud>5__1 = null; break; case 1: <>1__state = -1; break; } if ((Object)(object)(<hud>5__1 = GameObject.Find("/GAME/GUIManager/Canvas_HUD/")) == (Object)null) { <>2__current = null; <>1__state = 1; return true; } if ((Object)(object)<>4__this.promptObject != (Object)null) { Object.Destroy((Object)(object)<>4__this.promptObject); <>4__this.promptObject = null; } ((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)"[ReviveHotkey] Canvas_HUD found. Creating revive prompt..."); <>4__this.CreateRevivePrompt(<hud>5__1); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private ConfigEntry<KeyCode> reviveKey; private ConfigEntry<int> reviveLimit; private ConfigEntry<float> reviveCooldownSeconds; private int reviveCountUsed = 0; private float lastReviveTime = -999f; private FieldInfo passedOutField; private FieldInfo fullyPassedOutField; private FieldInfo deadField; private GameObject promptObject; private Text promptText; private void Awake() { reviveKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "ReviveKey", (KeyCode)122, "Key used to revive yourself when unconscious"); reviveLimit = ((BaseUnityPlugin)this).Config.Bind<int>("General", "ReviveLimit", -1, "How many times you can use the revive key (-1 = infinite)"); reviveCooldownSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ReviveCooldownSeconds", 0f, "Delay (in seconds) between revive attempts (0 = no delay)"); FieldInfo[] fields = typeof(CharacterData).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo[] array = fields; foreach (FieldInfo fieldInfo in array) { if (fieldInfo.Name == "passedOut") { passedOutField = fieldInfo; } else if (fieldInfo.Name == "fullyPassedOut") { fullyPassedOutField = fieldInfo; } else if (fieldInfo.Name == "dead") { deadField = fieldInfo; } } if (passedOutField == null || fullyPassedOutField == null || deadField == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Could not reflect all required unconsciousness fields (passedOut, fullyPassedOut, dead)."); } else { ((BaseUnityPlugin)this).Logger.LogInfo((object)"ReviveHotkey ready — all required fields located."); } SceneManager.sceneLoaded += OnSceneLoaded; } private void OnDestroy() { SceneManager.sceneLoaded -= OnSceneLoaded; } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { ((MonoBehaviour)this).StartCoroutine(WaitForHUDAndCreatePrompt()); } private void Update() { //IL_00dd: Unknown result type (might be due to invalid IL or missing references) Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter != (Object)null && (Object)(object)localCharacter.data != (Object)null) { bool active = false; if (passedOutField != null && fullyPassedOutField != null && deadField != null) { bool flag = (bool)passedOutField.GetValue(localCharacter.data); bool flag2 = (bool)fullyPassedOutField.GetValue(localCharacter.data); bool flag3 = (bool)deadField.GetValue(localCharacter.data); if (!flag3 && flag && flag2) { active = true; } } if ((Object)(object)promptObject != (Object)null) { promptObject.SetActive(active); } } if (Input.GetKeyDown(reviveKey.Value)) { TryRevive(); } } private void TryRevive() { //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null || (Object)(object)((MonoBehaviourPun)localCharacter).photonView == (Object)null || (Object)(object)localCharacter.data == (Object)null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Local character or required components not found."); return; } if (passedOutField == null || fullyPassedOutField == null || deadField == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Cannot proceed — reflection failed for one or more required fields."); return; } if (Time.time - lastReviveTime < reviveCooldownSeconds.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Revive blocked: Cooldown active. Wait {reviveCooldownSeconds.Value - (Time.time - lastReviveTime):0.0}s more."); return; } bool flag = (bool)passedOutField.GetValue(localCharacter.data); bool flag2 = (bool)fullyPassedOutField.GetValue(localCharacter.data); if ((bool)deadField.GetValue(localCharacter.data)) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Revive blocked: Player is dead."); return; } if (!(flag && flag2)) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Revive blocked: Player is not fully unconscious."); return; } if (reviveLimit.Value >= 0 && reviveCountUsed >= reviveLimit.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Revive blocked: revive limit reached."); return; } reviveCountUsed++; lastReviveTime = Time.time; Vector3 val = localCharacter.Head + new Vector3(0f, 4f, 0f); ((MonoBehaviourPun)localCharacter).photonView.RPC("RPCA_ReviveAtPosition", (RpcTarget)0, new object[2] { val, false }); ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("Revive called! Revives used: {0}/{1}", reviveCountUsed, (reviveLimit.Value < 0) ? "infinite" : reviveLimit.Value.ToString())); } [IteratorStateMachine(typeof(<WaitForHUDAndCreatePrompt>d__15))] private IEnumerator WaitForHUDAndCreatePrompt() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForHUDAndCreatePrompt>d__15(0) { <>4__this = this }; } private void CreateRevivePrompt(GameObject hud) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) promptObject = new GameObject("RevivePrompt", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Text) }); promptObject.transform.SetParent(hud.transform, false); RectTransform component = promptObject.GetComponent<RectTransform>(); component.anchorMin = new Vector2(0.5f, 0.5f); component.anchorMax = new Vector2(0.5f, 0.5f); component.anchoredPosition = Vector2.zero; component.sizeDelta = new Vector2(800f, 200f); promptText = promptObject.GetComponent<Text>(); promptText.alignment = (TextAnchor)4; promptText.font = Resources.GetBuiltinResource<Font>("Arial.ttf"); promptText.fontSize = 30; ((Graphic)promptText).color = Color.red; promptText.text = $"Press [{reviveKey.Value}] to Revive"; promptObject.SetActive(false); ((BaseUnityPlugin)this).Logger.LogInfo((object)"[ReviveHotkey] Revive prompt created."); } }