Decompiled source of K Y S v1.1.0

tony4twentys-K.Y.S.dll

Decompiled 4 hours ago
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<KeyCode> KysKey;

		internal static ConfigEntry<KeyCode> KysModifier;

		internal static ConfigEntry<bool> KysModifierToggle;

		internal static ConfigEntry<KeyCode> ToggleKey;

		internal static ConfigEntry<KeyCode> ToggleModifier;

		internal static ConfigEntry<bool> ToggleModifierRequired;

		internal static ConfigEntry<bool> HideAllNotifications;

		internal static ConfigEntry<bool> KeepOnNotifierUntilOff;

		internal static ConfigEntry<bool> PreviewBothNotifiers;

		internal static ConfigEntry<float> PopupSeconds;

		internal static ConfigEntry<string> OnColor;

		internal static ConfigEntry<string> OffColor;

		internal static ConfigEntry<int> OnSize;

		internal static ConfigEntry<int> OffSize;

		internal static ConfigEntry<float> OnPosX;

		internal static ConfigEntry<float> OnPosY;

		internal static ConfigEntry<float> OffPosX;

		internal static ConfigEntry<float> 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<bool>("Hotkey", "kysModifierToggle", true, "Require modifier to be held with kysKey to trigger death.");
			KysModifier = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Hotkey", "kysModifier", (KeyCode)308, "Modifier key for death.");
			KysKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Hotkey", "kysKey", (KeyCode)100, "Key that triggers death.");
			ToggleModifierRequired = ((BaseUnityPlugin)this).Config.Bind<bool>("Toggle", "kysToggleModifierToggle", true, "Require modifier to toggle the suicide system.");
			ToggleModifier = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Toggle", "kysToggleModifier", (KeyCode)308, "Modifier key for toggling.");
			ToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Toggle", "kysToggleKey", (KeyCode)115, "Key to toggle suicide system.");
			HideAllNotifications = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "HideAllNotifications", false, "Hide on-screen K.Y.S alerts.");
			KeepOnNotifierUntilOff = ((BaseUnityPlugin)this).Config.Bind<bool>("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<bool>("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<float>("UI", "PopupSeconds", 5f, "How long timed ON/OFF alerts stay on screen.");
			OnColor = ((BaseUnityPlugin)this).Config.Bind<string>("UI", "OnColor", "#FF0000", "K.Y.S ON alert color.");
			OffColor = ((BaseUnityPlugin)this).Config.Bind<string>("UI", "OffColor", "#00FF00", "K.Y.S OFF alert color.");
			OnSize = ((BaseUnityPlugin)this).Config.Bind<int>("UI", "OnSize", 80, "K.Y.S ON text size.");
			OffSize = ((BaseUnityPlugin)this).Config.Bind<int>("UI", "OffSize", 80, "K.Y.S OFF text size.");
			OnPosX = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "OnPosX", 0f, "K.Y.S ON anchored X.");
			OnPosY = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "OnPosY", -200f, "K.Y.S ON anchored Y.");
			OffPosX = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "OffPosX", 0f, "K.Y.S OFF anchored X.");
			OffPosY = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "OffPosY", -200f, "K.Y.S OFF anchored Y.");
			BindLiveUi<bool>(HideAllNotifications);
			BindLiveUi<bool>(KeepOnNotifierUntilOff);
			BindLiveUi<bool>(PreviewBothNotifiers);
			BindLiveUi<float>(PopupSeconds);
			BindLiveUi<string>(OnColor);
			BindLiveUi<string>(OffColor);
			BindLiveUi<int>(OnSize);
			BindLiveUi<int>(OffSize);
			BindLiveUi<float>(OnPosX);
			BindLiveUi<float>(OnPosY);
			BindLiveUi<float>(OffPosX);
			BindLiveUi<float>(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<T>(ConfigEntry<T> 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<KeyCode> key, ConfigEntry<KeyCode> modifier, ConfigEntry<bool> 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<string> 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<Canvas>();
				obj.renderMode = (RenderMode)0;
				obj.sortingOrder = 9400;
				obj.additionalShaderChannels = (AdditionalCanvasShaderChannels)25;
				CanvasScaler obj2 = _canvasObject.AddComponent<CanvasScaler>();
				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<float> x, ConfigEntry<float> 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<RectTransform>();
			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<TextMeshProUGUI>();
			((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<TextMeshProUGUI>(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<TextMeshProUGUI>((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;
		}
	}
}