using System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using TMPro; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: AssemblyTitle("K.Y.S")] [assembly: AssemblyDescription("Toggleable instant death hotkey for PEAK.")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("tony4twenty")] [assembly: AssemblyProduct("K.Y.S")] [assembly: AssemblyCopyright("Copyright © tony4twenty 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("361d37ad-d43b-4908-bdd2-02729cf3904d")] [assembly: AssemblyFileVersion("1.1.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.0.0")] [module: UnverifiableCode] namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } } namespace KYS { [BepInPlugin("tony4twentys.kys", "K.Y.S", "1.1.0")] [BepInProcess("PEAK.exe")] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "tony4twentys.kys"; public const string PluginName = "K.Y.S"; public const string PluginVersion = "1.1.0"; internal static ConfigEntry KysKey; internal static ConfigEntry KysModifier; internal static ConfigEntry KysModifierToggle; internal static ConfigEntry ToggleKey; internal static ConfigEntry ToggleModifier; internal static ConfigEntry ToggleModifierRequired; internal static ConfigEntry HideAllNotifications; internal static ConfigEntry KeepOnNotifierUntilOff; internal static ConfigEntry PreviewBothNotifiers; internal static ConfigEntry PopupSeconds; internal static ConfigEntry OnColor; internal static ConfigEntry OffColor; internal static ConfigEntry OnSize; internal static ConfigEntry OffSize; internal static ConfigEntry OnPosX; internal static ConfigEntry OnPosY; internal static ConfigEntry OffPosX; internal static ConfigEntry OffPosY; private bool _loggedDieFailure; internal static Plugin Instance { get; private set; } internal static ManualLogSource Log { get; private set; } internal static bool SuicideEnabled { get; private set; } private void Awake() { Instance = this; Log = ((BaseUnityPlugin)this).Logger; KysModifierToggle = ((BaseUnityPlugin)this).Config.Bind("Hotkey", "kysModifierToggle", true, "Require modifier to be held with kysKey to trigger death."); KysModifier = ((BaseUnityPlugin)this).Config.Bind("Hotkey", "kysModifier", (KeyCode)308, "Modifier key for death."); KysKey = ((BaseUnityPlugin)this).Config.Bind("Hotkey", "kysKey", (KeyCode)100, "Key that triggers death."); ToggleModifierRequired = ((BaseUnityPlugin)this).Config.Bind("Toggle", "kysToggleModifierToggle", true, "Require modifier to toggle the suicide system."); ToggleModifier = ((BaseUnityPlugin)this).Config.Bind("Toggle", "kysToggleModifier", (KeyCode)308, "Modifier key for toggling."); ToggleKey = ((BaseUnityPlugin)this).Config.Bind("Toggle", "kysToggleKey", (KeyCode)115, "Key to toggle suicide system."); HideAllNotifications = ((BaseUnityPlugin)this).Config.Bind("UI", "HideAllNotifications", false, "Hide on-screen K.Y.S alerts."); KeepOnNotifierUntilOff = ((BaseUnityPlugin)this).Config.Bind("UI", "KeepOnNotifierUntilOff", true, "If on, the K.Y.S ON text stays on screen until suicide is toggled off. If off, ON fades like OFF."); PreviewBothNotifiers = ((BaseUnityPlugin)this).Config.Bind("UI", "PreviewBothNotifiers", false, "Show K.Y.S ON and K.Y.S OFF together so you can place, size, and recolor them. Edits apply immediately. Turn off when finished."); PopupSeconds = ((BaseUnityPlugin)this).Config.Bind("UI", "PopupSeconds", 5f, "How long timed ON/OFF alerts stay on screen."); OnColor = ((BaseUnityPlugin)this).Config.Bind("UI", "OnColor", "#FF0000", "K.Y.S ON alert color."); OffColor = ((BaseUnityPlugin)this).Config.Bind("UI", "OffColor", "#00FF00", "K.Y.S OFF alert color."); OnSize = ((BaseUnityPlugin)this).Config.Bind("UI", "OnSize", 80, "K.Y.S ON text size."); OffSize = ((BaseUnityPlugin)this).Config.Bind("UI", "OffSize", 80, "K.Y.S OFF text size."); OnPosX = ((BaseUnityPlugin)this).Config.Bind("UI", "OnPosX", 0f, "K.Y.S ON anchored X."); OnPosY = ((BaseUnityPlugin)this).Config.Bind("UI", "OnPosY", -200f, "K.Y.S ON anchored Y."); OffPosX = ((BaseUnityPlugin)this).Config.Bind("UI", "OffPosX", 0f, "K.Y.S OFF anchored X."); OffPosY = ((BaseUnityPlugin)this).Config.Bind("UI", "OffPosY", -200f, "K.Y.S OFF anchored Y."); BindLiveUi(HideAllNotifications); BindLiveUi(KeepOnNotifierUntilOff); BindLiveUi(PreviewBothNotifiers); BindLiveUi(PopupSeconds); BindLiveUi(OnColor); BindLiveUi(OffColor); BindLiveUi(OnSize); BindLiveUi(OffSize); BindLiveUi(OnPosX); BindLiveUi(OnPosY); BindLiveUi(OffPosX); BindLiveUi(OffPosY); KysHud.Initialize(((Component)this).transform); KysHud.ApplyLiveSettings(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"K.Y.S v1.1.0 loaded."); } private void OnDestroy() { KysHud.Shutdown(); if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } private void Update() { KysHud.Tick(); if (!IsGameplayInputBlocked()) { if (WasPressed(ToggleKey, ToggleModifier, ToggleModifierRequired)) { ToggleSuicide(); } if (SuicideEnabled && WasPressed(KysKey, KysModifier, KysModifierToggle)) { KillYourself(); } } } private void ToggleSuicide() { SuicideEnabled = !SuicideEnabled; ((BaseUnityPlugin)this).Logger.LogInfo((object)("KYS: Suicide ability toggled " + (SuicideEnabled ? "ON" : "OFF"))); if (!KysHud.Previewing) { if (SuicideEnabled) { KysHud.ShowOn(); } else { KysHud.ShowOff(); } } } private static void BindLiveUi(ConfigEntry entry) { if (entry != null) { entry.SettingChanged += delegate { KysHud.ApplyLiveSettings(); }; } } private void KillYourself() { Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter.data == (Object)null || localCharacter.data.dead || (Object)(object)localCharacter.view == (Object)null) { return; } try { Character.Die(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"KYS: Suicide triggered."); } catch (Exception ex) { if (!_loggedDieFailure) { _loggedDieFailure = true; ((BaseUnityPlugin)this).Logger.LogError((object)("KYS: Die failed once: " + ex)); } } } private static bool WasPressed(ConfigEntry key, ConfigEntry modifier, ConfigEntry requireModifier) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) if (key == null || (int)key.Value == 0) { return false; } if (!Input.GetKeyDown(key.Value)) { return false; } if (requireModifier != null && requireModifier.Value) { if (modifier != null && (int)modifier.Value != 0) { return Input.GetKey(modifier.Value); } return false; } return true; } private static bool IsGameplayInputBlocked() { try { if (GUIManager.InPauseMenu) { return true; } GUIManager instance = GUIManager.instance; return (Object)(object)instance != (Object)null && instance.windowBlockingInput; } catch { return false; } } internal static Color ParseColor(ConfigEntry entry, Color fallback) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) if (entry == null || string.IsNullOrWhiteSpace(entry.Value)) { return fallback; } string text = entry.Value.Trim(); if (text.Length == 0 || text[0] != '#') { text = "#" + text; } Color result = default(Color); if (ColorUtility.TryParseHtmlString(text, ref result)) { return result; } return fallback; } } internal static class KysHud { private sealed class AlertLabel { internal GameObject Root; internal RectTransform Rect; internal TextMeshProUGUI Label; internal float HideAt; } private static readonly Color OnFallback = Color.red; private static readonly Color OffFallback = Color.green; private static GameObject _canvasObject; private static AlertLabel _onAlert; private static AlertLabel _offAlert; private static TMP_FontAsset _cachedFont; private static int _cachedSceneHandle = -1; private static bool _previewing; internal static bool Previewing => _previewing; internal static void Initialize(Transform parent) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_canvasObject != (Object)null)) { _canvasObject = new GameObject("KYSAlertCanvas"); if ((Object)(object)parent != (Object)null) { _canvasObject.transform.SetParent(parent, false); } Canvas obj = _canvasObject.AddComponent(); obj.renderMode = (RenderMode)0; obj.sortingOrder = 9400; obj.additionalShaderChannels = (AdditionalCanvasShaderChannels)25; CanvasScaler obj2 = _canvasObject.AddComponent(); obj2.uiScaleMode = (ScaleMode)1; obj2.referenceResolution = new Vector2(1920f, 1080f); obj2.matchWidthOrHeight = 1f; _onAlert = CreateAlert("OnAlert"); _offAlert = CreateAlert("OffAlert"); HideAll(); } } internal static void Shutdown() { if ((Object)(object)_canvasObject != (Object)null) { Object.Destroy((Object)(object)_canvasObject); } _canvasObject = null; _onAlert = null; _offAlert = null; _cachedFont = null; _cachedSceneHandle = -1; _previewing = false; } internal static void Tick() { if (_onAlert == null) { return; } if (WantPreview()) { if (!_previewing) { ApplyLiveSettings(); } ApplyFont(_onAlert.Label); ApplyFont(_offAlert.Label); return; } if (_previewing) { _previewing = false; RestoreFromSuicideState(); return; } if (Plugin.SuicideEnabled && PersistOn()) { if (NotificationsHidden()) { Hide(_onAlert); } else if (!_onAlert.Root.activeSelf) { ShowOn(); } else { ApplyFont(_onAlert.Label); } } else { HideIfExpired(_onAlert); } HideIfExpired(_offAlert); } internal static void ApplyLiveSettings() { if (_onAlert == null) { return; } if (WantPreview()) { ShowPreviewBoth(); return; } if (_previewing) { _previewing = false; RestoreFromSuicideState(); return; } if (NotificationsHidden()) { HideAll(); return; } if (_onAlert.Root.activeSelf) { ApplyAppearance(_onAlert, on: true); if (Plugin.SuicideEnabled && PersistOn()) { _onAlert.HideAt = float.PositiveInfinity; } else if (Plugin.SuicideEnabled) { _onAlert.HideAt = Time.unscaledTime + PopupDuration(); } } else if (Plugin.SuicideEnabled && PersistOn()) { ShowOn(); } if (_offAlert.Root.activeSelf) { ApplyAppearance(_offAlert, on: false); } } internal static void ShowOn() { if (WantPreview()) { ShowPreviewBoth(); return; } if (NotificationsHidden()) { HideAll(); return; } Hide(_offAlert); ForceShow(_onAlert, on: true, PersistOn()); } internal static void ShowOff() { if (WantPreview()) { ShowPreviewBoth(); return; } Hide(_onAlert); if (!NotificationsHidden()) { ForceShow(_offAlert, on: false, persist: false); } } private static bool PersistOn() { if (Plugin.KeepOnNotifierUntilOff != null) { return Plugin.KeepOnNotifierUntilOff.Value; } return true; } private static bool NotificationsHidden() { if (Plugin.HideAllNotifications != null) { return Plugin.HideAllNotifications.Value; } return false; } private static bool WantPreview() { if (Plugin.PreviewBothNotifiers != null) { return Plugin.PreviewBothNotifiers.Value; } return false; } private static void ShowPreviewBoth() { _previewing = true; ForceShow(_onAlert, on: true, persist: true); ForceShow(_offAlert, on: false, persist: true); } private static void RestoreFromSuicideState() { if (NotificationsHidden()) { HideAll(); } else if (Plugin.SuicideEnabled) { ShowOn(); } else { HideAll(); } } private static void ForceShow(AlertLabel alert, bool on, bool persist) { if (alert != null && !((Object)(object)alert.Label == (Object)null)) { ApplyAppearance(alert, on); alert.Root.SetActive(true); alert.HideAt = (persist ? float.PositiveInfinity : (Time.unscaledTime + PopupDuration())); } } private static void ApplyAppearance(AlertLabel alert, bool on) { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) if (alert != null && !((Object)(object)alert.Label == (Object)null)) { ((TMP_Text)alert.Label).text = (on ? "K.Y.S ON" : "K.Y.S OFF"); ((TMP_Text)alert.Label).fontSize = ((!on) ? ((Plugin.OffSize != null) ? Plugin.OffSize.Value : 80) : ((Plugin.OnSize != null) ? Plugin.OnSize.Value : 80)); ((Graphic)alert.Label).color = (on ? Plugin.ParseColor(Plugin.OnColor, OnFallback) : Plugin.ParseColor(Plugin.OffColor, OffFallback)); ApplyFont(alert.Label); alert.Rect.anchoredPosition = (on ? Pos(Plugin.OnPosX, Plugin.OnPosY, 0f, -200f) : Pos(Plugin.OffPosX, Plugin.OffPosY, 0f, -200f)); } } private static float PopupDuration() { if (Plugin.PopupSeconds == null) { return 5f; } return Mathf.Max(0.25f, Plugin.PopupSeconds.Value); } private static Vector2 Pos(ConfigEntry x, ConfigEntry y, float fallbackX, float fallbackY) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) return new Vector2(x?.Value ?? fallbackX, y?.Value ?? fallbackY); } private static void HideIfExpired(AlertLabel alert) { if (alert != null && alert.Root.activeSelf && Time.unscaledTime >= alert.HideAt) { Hide(alert); } } private static void Hide(AlertLabel alert) { if (alert != null && (Object)(object)alert.Root != (Object)null) { alert.Root.SetActive(false); } } private static void HideAll() { Hide(_onAlert); Hide(_offAlert); } private static AlertLabel CreateAlert(string name) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[2] { typeof(RectTransform), typeof(CanvasRenderer) }); val.transform.SetParent(_canvasObject.transform, false); RectTransform component = val.GetComponent(); component.anchorMin = new Vector2(0.5f, 0.5f); component.anchorMax = new Vector2(0.5f, 0.5f); component.pivot = new Vector2(0.5f, 0.5f); component.sizeDelta = new Vector2(900f, 120f); TextMeshProUGUI val2 = val.AddComponent(); ((TMP_Text)val2).alignment = (TextAlignmentOptions)514; ((TMP_Text)val2).fontStyle = (FontStyles)0; ((Graphic)val2).raycastTarget = false; ((TMP_Text)val2).enableWordWrapping = false; ((TMP_Text)val2).overflowMode = (TextOverflowModes)0; ApplyFont(val2); val.SetActive(false); return new AlertLabel { Root = val, Rect = component, Label = val2 }; } private static void ApplyFont(TextMeshProUGUI text) { if (!((Object)(object)text == (Object)null)) { TMP_FontAsset gameFont = GetGameFont(); if ((Object)(object)gameFont != (Object)null) { ((TMP_Text)text).font = gameFont; } ((TMP_Text)text).fontStyle = (FontStyles)0; } } private static TMP_FontAsset GetGameFont() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) Scene activeScene = SceneManager.GetActiveScene(); int num = SceneHandle.op_Implicit(((Scene)(ref activeScene)).handle); if ((Object)(object)_cachedFont != (Object)null && _cachedSceneHandle == num) { return _cachedFont; } try { if ((Object)(object)GUIManager.instance != (Object)null) { TextMeshProUGUI componentInChildren = ((Component)GUIManager.instance).GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null && (Object)(object)((TMP_Text)componentInChildren).font != (Object)null) { _cachedFont = ((TMP_Text)componentInChildren).font; _cachedSceneHandle = num; return _cachedFont; } } } catch { } try { TextMeshProUGUI val = Object.FindFirstObjectByType((FindObjectsInactive)1); if ((Object)(object)val != (Object)null && (Object)(object)((TMP_Text)val).font != (Object)null) { _cachedFont = ((TMP_Text)val).font; _cachedSceneHandle = num; return _cachedFont; } } catch { } return _cachedFont; } } }