Decompiled source of No TSA v1.0.0

tony4twentys-No TSA.dll

Decompiled a week ago
using System;
using System.Collections;
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 HarmonyLib;
using Photon.Pun;
using TMPro;
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: AssemblyTitle("No TSA")]
[assembly: AssemblyDescription("Lets PEAK Airport lobby hunger, fall damage, and item afflictions work like a normal run.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("tony4twenty")]
[assembly: AssemblyProduct("No TSA")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("bc34ad11-6ecb-4291-b51e-6a275edd47a6")]
[assembly: AssemblyFileVersion("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.0.0.0")]
[module: UnverifiableCode]
namespace NoTSA;

[BepInPlugin("tony4twentys.No_TSA", "No TSA", "1.0.0")]
[BepInProcess("PEAK.exe")]
public class Plugin : BaseUnityPlugin
{
	public const string PluginGuid = "tony4twentys.No_TSA";

	public const string PluginName = "No TSA";

	public const string PluginVersion = "1.0.0";

	private ConfigEntry<bool> _enabled;

	private Harmony _harmony;

	internal static Plugin Instance { get; private set; }

	internal static ManualLogSource Log { get; private set; }

	internal static bool IsEnabled => (Object)(object)Instance == (Object)null || Instance._enabled == null || Instance._enabled.Value;

	private void Awake()
	{
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Expected O, but got Unknown
		Instance = this;
		Log = ((BaseUnityPlugin)this).Logger;
		_enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "When enabled, the Airport lobby applies hunger, fall damage, and item afflictions like a normal run.");
		_harmony = new Harmony("tony4twentys.No_TSA");
		_harmony.PatchAll(typeof(Plugin).Assembly);
		RespawnHud.Initialize(((Component)this).transform);
		SceneManager.sceneLoaded += OnSceneLoaded;
		if (GameAccess.InAirport == null)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)"Could not bind CharacterAfflictions.m_inAirport. Airport statuses will stay blocked.");
		}
		((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} v{1} loaded.", "No TSA", "1.0.0"));
	}

	private void Update()
	{
		AirportRespawn.Tick();
	}

	private static void OnSceneLoaded(Scene scene, LoadSceneMode mode)
	{
		GameUiFont.Invalidate();
		if (((Scene)(ref scene)).name != "Airport")
		{
			AirportRespawn.Cancel();
		}
	}

	private void OnDestroy()
	{
		SceneManager.sceneLoaded -= OnSceneLoaded;
		AirportRespawn.Cancel();
		RespawnHud.Shutdown();
		if (_harmony != null)
		{
			_harmony.UnpatchSelf();
		}
		if ((Object)(object)Instance == (Object)(object)this)
		{
			Instance = null;
		}
	}
}
[HarmonyPatch(typeof(CharacterAfflictions), "Awake")]
internal static class AirportAfflictionsAwakePatch
{
	private static void Postfix(CharacterAfflictions __instance)
	{
		AirportShield.Disable(__instance, "Awake");
	}
}
[HarmonyPatch(typeof(CharacterAfflictions), "AddStatus")]
internal static class AirportStatusPatch
{
	private static void Prefix(CharacterAfflictions __instance)
	{
		AirportShield.Disable(__instance, "AddStatus");
	}
}
[HarmonyPatch(typeof(Character), "get_inAirport")]
internal static class CharacterInAirportPatch
{
	private static void Postfix(ref bool __result)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		Scene activeScene = SceneManager.GetActiveScene();
		__result = ((Scene)(ref activeScene)).name == "Airport";
	}
}
[HarmonyPatch(typeof(Character), "RPCA_Die")]
internal static class AirportDeathRespawnPatch
{
	private static void Postfix(Character __instance)
	{
		AirportRespawn.HandleLocalDeath(__instance);
	}
}
[HarmonyPatch(typeof(Character), "CheckEndGame")]
internal static class AirportCheckEndGamePatch
{
	private static bool Prefix()
	{
		return !Plugin.IsEnabled || !AirportRespawn.IsAirportScene;
	}
}
[HarmonyPatch(typeof(Skelleton), "Update")]
internal static class AirportSkeletonCleanupPatch
{
	private static void Postfix(Skelleton __instance)
	{
		if (!((Object)(object)__instance == (Object)null))
		{
			Character val = ((GameAccess.SkelletonSource != null) ? GameAccess.SkelletonSource.Invoke(__instance) : null);
			if ((Object)(object)val == (Object)null)
			{
				Object.Destroy((Object)(object)((Component)__instance).gameObject);
			}
		}
	}
}
internal static class AirportShield
{
	internal static void Disable(CharacterAfflictions afflictions, string reason)
	{
		if (Plugin.IsEnabled && !((Object)(object)afflictions == (Object)null) && GameAccess.InAirport.Invoke(afflictions))
		{
			GameAccess.InAirport.Invoke(afflictions) = false;
			Character character = afflictions.character;
			string arg = (((Object)(object)character != (Object)null) ? ((Object)((Component)character).gameObject).name : ((Object)((Component)afflictions).gameObject).name);
			Plugin.Log.LogInfo((object)$"Removed Airport status shield on {arg} ({reason}).");
		}
	}
}
internal static class AirportRespawn
{
	private const float StepSeconds = 1f;

	private static bool _running;

	internal static bool IsAirportScene
	{
		get
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			return ((Scene)(ref activeScene)).name == "Airport";
		}
	}

	internal static void Tick()
	{
		RespawnHud.Tick();
	}

	internal static void HandleLocalDeath(Character character)
	{
		if (Plugin.IsEnabled && !_running && !((Object)(object)character == (Object)null) && character.IsLocal && IsAirportScene)
		{
			((MonoBehaviour)Plugin.Instance).StartCoroutine(CountdownAndRespawn());
		}
	}

	internal static void Cancel()
	{
		_running = false;
		RespawnHud.Hide();
	}

	private static IEnumerator CountdownAndRespawn()
	{
		_running = true;
		Plugin.Log.LogInfo((object)"Airport death — starting 3-2-1 respawn.");
		for (int n = 3; n >= 1; n--)
		{
			if (!StillInAirportLobby())
			{
				Cancel();
				yield break;
			}
			RespawnHud.Show(n.ToString());
			float until = Time.unscaledTime + 1f;
			while (Time.unscaledTime < until)
			{
				if (!StillInAirportLobby())
				{
					Cancel();
					yield break;
				}
				yield return null;
			}
		}
		RespawnHud.Hide();
		CharacterSpawner spawner = Object.FindFirstObjectByType<CharacterSpawner>();
		if ((Object)(object)spawner == (Object)null)
		{
			Plugin.Log.LogError((object)"Airport respawn failed — no CharacterSpawner in the scene.");
			_running = false;
			yield break;
		}
		Character old = Character.localCharacter;
		CleanupSkeletons(old);
		if ((Object)(object)old != (Object)null && (Object)(object)((MonoBehaviourPun)old).photonView != (Object)null && ((MonoBehaviourPun)old).photonView.IsMine)
		{
			PhotonNetwork.Destroy(((Component)old).gameObject);
		}
		yield return null;
		if (!StillInAirportLobby())
		{
			Cancel();
			yield break;
		}
		spawner.hasSpawnedPlayer = false;
		spawner.SpawnSelfInAirport();
		Plugin.Log.LogInfo((object)"Respawned at the Airport lobby spawner.");
		_running = false;
	}

	internal static void CleanupSkeletons(Character source)
	{
		Skelleton[] array = Object.FindObjectsByType<Skelleton>((FindObjectsInactive)1, (FindObjectsSortMode)0);
		foreach (Skelleton val in array)
		{
			if (!((Object)(object)val == (Object)null))
			{
				Character val2 = ((GameAccess.SkelletonSource != null) ? GameAccess.SkelletonSource.Invoke(val) : null);
				if ((Object)(object)val2 == (Object)null || (Object)(object)val2 == (Object)(object)source)
				{
					Object.Destroy((Object)(object)((Component)val).gameObject);
				}
			}
		}
	}

	private static bool StillInAirportLobby()
	{
		return Plugin.IsEnabled && (Object)(object)Plugin.Instance != (Object)null && IsAirportScene;
	}
}
internal static class GameAccess
{
	internal static readonly FieldRef<CharacterAfflictions, bool> InAirport = AccessTools.FieldRefAccess<CharacterAfflictions, bool>("m_inAirport");

	internal static readonly FieldRef<Skelleton, Character> SkelletonSource = AccessTools.FieldRefAccess<Skelleton, Character>("spawnedFromCharacter");
}
internal static class GameUiFont
{
	private static TMP_FontAsset _cached;

	private static int _cachedSceneHandle = -1;

	internal static TMP_FontAsset Get()
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0009: 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)_cached != (Object)null && _cachedSceneHandle == num)
		{
			return _cached;
		}
		_cached = FindGameFont();
		_cachedSceneHandle = num;
		return _cached;
	}

	internal static void Apply(TextMeshProUGUI text)
	{
		if (!((Object)(object)text == (Object)null))
		{
			TMP_FontAsset val = Get();
			if ((Object)(object)val != (Object)null)
			{
				((TMP_Text)text).font = val;
			}
			((TMP_Text)text).fontStyle = (FontStyles)0;
		}
	}

	internal static void Invalidate()
	{
		_cached = null;
		_cachedSceneHandle = -1;
	}

	private static TMP_FontAsset FindGameFont()
	{
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		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)
				{
					return ((TMP_Text)componentInChildren).font;
				}
			}
		}
		catch
		{
		}
		try
		{
			TextMeshProUGUI val = Object.FindFirstObjectByType<TextMeshProUGUI>((FindObjectsInactive)1);
			if ((Object)(object)val != (Object)null && (Object)(object)((TMP_Text)val).font != (Object)null)
			{
				return ((TMP_Text)val).font;
			}
		}
		catch
		{
		}
		try
		{
			TextMeshProUGUI[] array = Resources.FindObjectsOfTypeAll<TextMeshProUGUI>();
			foreach (TextMeshProUGUI val2 in array)
			{
				if ((Object)(object)val2 == (Object)null || (Object)(object)((TMP_Text)val2).font == (Object)null)
				{
					continue;
				}
				Scene scene = ((Component)val2).gameObject.scene;
				if (((Scene)(ref scene)).IsValid())
				{
					scene = ((Component)val2).gameObject.scene;
					if (((Scene)(ref scene)).isLoaded)
					{
						return ((TMP_Text)val2).font;
					}
				}
			}
		}
		catch
		{
		}
		return null;
	}
}
internal static class RespawnHud
{
	private static readonly Color Cream = new Color(0.95f, 0.93f, 0.88f, 1f);

	private const float FontSize = 60f;

	private static GameObject _canvasObject;

	private static Canvas _canvas;

	private static TextMeshProUGUI _label;

	internal static void Initialize(Transform parent)
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Expected O, but got Unknown
		if (!((Object)(object)_canvasObject != (Object)null))
		{
			_canvasObject = new GameObject("NoTSA_RespawnHud");
			if ((Object)(object)parent != (Object)null)
			{
				_canvasObject.transform.SetParent(parent, false);
			}
			_canvas = CreateOverlayCanvas(_canvasObject, 9400);
			((Behaviour)_canvas).enabled = false;
			_label = CreateLabel(_canvasObject.transform, "Countdown", string.Empty);
			((Component)_label).gameObject.SetActive(false);
		}
	}

	internal static void Show(string text)
	{
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		Initialize(((Object)(object)Plugin.Instance != (Object)null) ? ((Component)Plugin.Instance).transform : null);
		if (!((Object)(object)_canvas == (Object)null) && !((Object)(object)_label == (Object)null))
		{
			GameUiFont.Apply(_label);
			((Graphic)_label).color = Cream;
			((TMP_Text)_label).fontSize = 60f;
			((TMP_Text)_label).text = text ?? string.Empty;
			((Component)_label).gameObject.SetActive(true);
			((Behaviour)_canvas).enabled = true;
		}
	}

	internal static void Hide()
	{
		if ((Object)(object)_label != (Object)null)
		{
			((TMP_Text)_label).text = string.Empty;
			((Component)_label).gameObject.SetActive(false);
		}
		if ((Object)(object)_canvas != (Object)null)
		{
			((Behaviour)_canvas).enabled = false;
		}
	}

	internal static void Tick()
	{
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)_canvas == (Object)null) && ((Behaviour)_canvas).enabled && !((Object)(object)_label == (Object)null) && ((Component)_label).gameObject.activeSelf)
		{
			GameUiFont.Apply(_label);
			((Graphic)_label).color = Cream;
			((TMP_Text)_label).fontSize = 60f;
		}
	}

	internal static void Shutdown()
	{
		if ((Object)(object)_canvasObject != (Object)null)
		{
			Object.Destroy((Object)(object)_canvasObject);
		}
		_canvasObject = null;
		_canvas = null;
		_label = null;
		GameUiFont.Invalidate();
	}

	private static Canvas CreateOverlayCanvas(GameObject root, int sortingOrder)
	{
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		Canvas val = root.GetComponent<Canvas>() ?? root.AddComponent<Canvas>();
		val.renderMode = (RenderMode)0;
		val.sortingOrder = sortingOrder;
		val.additionalShaderChannels = (AdditionalCanvasShaderChannels)25;
		CanvasScaler val2 = root.GetComponent<CanvasScaler>() ?? root.AddComponent<CanvasScaler>();
		val2.uiScaleMode = (ScaleMode)1;
		val2.referenceResolution = new Vector2(1920f, 1080f);
		val2.matchWidthOrHeight = 1f;
		if ((Object)(object)root.GetComponent<GraphicRaycaster>() == (Object)null)
		{
			((Behaviour)root.AddComponent<GraphicRaycaster>()).enabled = false;
		}
		return val;
	}

	private static TextMeshProUGUI CreateLabel(Transform parent, string name, string text)
	{
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Expected O, but got Unknown
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: 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_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: 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(parent, false);
		RectTransform component = val.GetComponent<RectTransform>();
		Vector2 val2 = default(Vector2);
		((Vector2)(ref val2))..ctor(0.5f, 0.5f);
		component.anchorMax = val2;
		component.anchorMin = val2;
		component.pivot = new Vector2(0.5f, 0.5f);
		component.anchoredPosition = Vector2.zero;
		component.sizeDelta = new Vector2(900f, 120f);
		TextMeshProUGUI val3 = val.AddComponent<TextMeshProUGUI>();
		((TMP_Text)val3).text = text ?? string.Empty;
		((TMP_Text)val3).fontSize = 60f;
		((TMP_Text)val3).fontStyle = (FontStyles)0;
		((TMP_Text)val3).alignment = (TextAlignmentOptions)514;
		((Graphic)val3).color = Cream;
		((Graphic)val3).raycastTarget = false;
		((MaskableGraphic)val3).maskable = true;
		((TMP_Text)val3).overflowMode = (TextOverflowModes)0;
		((TMP_Text)val3).enableWordWrapping = false;
		GameUiFont.Apply(val3);
		return val3;
	}
}