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