using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("ATLYSS_PleaseHaveASeat")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Eleen")] [assembly: AssemblyProduct("ATLYSS_PleaseHaveASeat")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("6a8b4633-6d6f-491c-8106-48d4fde542f8")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] namespace Eleen.Atlyss.PleaseHaveASeat { [BepInPlugin("com.eleen.atlyss.pleasehaveaseat", "Please, Have a Seat.", "1.0.0")] public class HaveASeatPlugin : BaseUnityPlugin { internal static ConfigEntry ToggleKey; private Harmony _harmony; private void Awake() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown ToggleKey = ((BaseUnityPlugin)this).Config.Bind("General", "ToggleKey", (KeyCode)290, "Key to toggle the player selection GUI."); SeatManager.Initialize(((BaseUnityPlugin)this).Logger); _harmony = new Harmony("com.eleen.atlyss.pleasehaveaseat"); _harmony.PatchAll(); ((Component)this).gameObject.AddComponent(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Have a Seat loaded."); } private void OnDestroy() { SeatManager.Shutdown(); Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } internal class SeatGui : MonoBehaviour { private static readonly KeyCode DefaultKey = (KeyCode)290; private const float PlayerListRefreshInterval = 1f; private bool _showWindow; private Rect _windowRect = new Rect(20f, 20f, 360f, 400f); private Vector2 _scrollPos; private CursorLockMode _savedLockState; private bool _savedVisible; private bool _waitingForKey; private Player[] _cachedPlayers; private float _refreshTimer; private void Update() { //IL_0070: Unknown result type (might be due to invalid IL or missing references) if (_showWindow) { Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; _refreshTimer -= Time.unscaledDeltaTime; if (_refreshTimer <= 0f) { _cachedPlayers = Object.FindObjectsOfType(); _refreshTimer = 1f; SeatManager.CleanupStaleTargets(); } } if (!_waitingForKey && Input.GetKeyDown(HaveASeatPlugin.ToggleKey.Value)) { if (_showWindow) { CloseWindow(); } else { OpenWindow(); } } } private void OpenWindow() { //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) _savedLockState = Cursor.lockState; _savedVisible = Cursor.visible; Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; _cachedPlayers = Object.FindObjectsOfType(); _refreshTimer = 1f; _showWindow = true; } private void CloseWindow() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) _waitingForKey = false; _cachedPlayers = null; Cursor.lockState = _savedLockState; Cursor.visible = _savedVisible; _showWindow = false; } private void OnDisable() { if (_showWindow) { CloseWindow(); } } private void OnGUI() { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown //IL_007e: 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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Invalid comparison between Unknown and I4 //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Invalid comparison between Unknown and I4 //IL_0041: Unknown result type (might be due to invalid IL or missing references) if (!_showWindow) { return; } if (_waitingForKey) { Event current = Event.current; if ((int)current.type == 4 && (int)current.keyCode > 0) { HaveASeatPlugin.ToggleKey.Value = current.keyCode; _waitingForKey = false; current.Use(); } } _windowRect = GUILayout.Window(948201, _windowRect, new WindowFunction(DrawWindow), "Have a Seat", Array.Empty()); } private void SitAllInZone(SitMode mode) { if (_cachedPlayers == null || (Object)(object)Player._mainPlayer == (Object)null) { return; } MapInstance network_playerMapInstance = Player._mainPlayer.Network_playerMapInstance; if ((Object)(object)network_playerMapInstance == (Object)null) { return; } Player[] cachedPlayers = _cachedPlayers; foreach (Player val in cachedPlayers) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)Player._mainPlayer) && !string.IsNullOrEmpty(val._nickname) && !((Object)(object)val.Network_playerMapInstance != (Object)(object)network_playerMapInstance) && !SeatManager.IsTarget(val)) { SeatManager.AddTarget(val, mode); } } } private void DrawWindow(int id) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0360: Unknown result type (might be due to invalid IL or missing references) //IL_0365: Unknown result type (might be due to invalid IL or missing references) //IL_03fc: Unknown result type (might be due to invalid IL or missing references) if (GUI.Button(new Rect(((Rect)(ref _windowRect)).width - 22f, 2f, 20f, 18f), "X")) { CloseWindow(); return; } GUILayout.Space(4f); _scrollPos = GUILayout.BeginScrollView(_scrollPos, Array.Empty()); bool flag = false; Player mainPlayer = Player._mainPlayer; if (_cachedPlayers != null && (Object)(object)mainPlayer != (Object)null && (Object)(object)mainPlayer.Network_playerMapInstance != (Object)null) { Player[] cachedPlayers = _cachedPlayers; foreach (Player val in cachedPlayers) { if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)mainPlayer || string.IsNullOrEmpty(val._nickname) || (Object)(object)mainPlayer.Network_playerMapInstance != (Object)(object)val.Network_playerMapInstance) { continue; } flag = true; SitMode? targetMode = SeatManager.GetTargetMode(val); string text = (string.IsNullOrEmpty(val._globalNickname) ? val._nickname : (val._nickname + " / @" + val._globalNickname)); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label(text, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.MinWidth(100f), GUILayout.ExpandWidth(true) }); if (!targetMode.HasValue) { if (GUILayout.Button("Sit", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(55f) })) { SeatManager.AddTarget(val, SitMode.Soft); } if (GUILayout.Button("Lock", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(55f) })) { SeatManager.AddTarget(val, SitMode.Force); } } else if (targetMode == SitMode.Soft) { if (GUILayout.Button("Unsit", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(114f) })) { SeatManager.RemoveTarget(val); } } else if (GUILayout.Button("Unlock", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(114f) })) { SeatManager.RemoveTarget(val); } GUILayout.EndHorizontal(); } } if (!flag) { GUILayout.Label("No other players nearby.", Array.Empty()); } GUILayout.EndScrollView(); GUILayout.Space(4f); GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button("Sit All in Zone", Array.Empty())) { SitAllInZone(SitMode.Soft); } if (GUILayout.Button("Lock All in Zone", Array.Empty())) { SitAllInZone(SitMode.Force); } GUILayout.EndHorizontal(); if (GUILayout.Button("Release All", Array.Empty())) { SeatManager.RemoveAllTargets(); } GUILayout.Space(8f); GUILayout.Box("", (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.ExpandWidth(true), GUILayout.Height(1f) }); GUILayout.Space(4f); GUILayout.BeginHorizontal(Array.Empty()); object obj; if (!_waitingForKey) { KeyCode value = HaveASeatPlugin.ToggleKey.Value; obj = "Toggle Key: " + ((object)(KeyCode)(ref value)).ToString(); } else { obj = "Press any key..."; } string text2 = (string)obj; GUILayout.Label(text2, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); if (!_waitingForKey) { if (GUILayout.Button("Bind", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) })) { _waitingForKey = true; } if (GUILayout.Button("Reset", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) })) { HaveASeatPlugin.ToggleKey.Value = DefaultKey; } } else if (GUILayout.Button("Cancel", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) })) { _waitingForKey = false; } GUILayout.EndHorizontal(); GUI.DragWindow(); } } internal enum SitMode : byte { Soft, Force } internal static class SeatManager { private class TargetInfo { public Player Player; public PlayerVisual Visual; public Animator Animator; public PlayerMove Move; public PlayerWater Water; public bool IsForceSitting; public SitMode Mode; } private static ManualLogSource _log; private static FieldInfo _fi_pv_pMove; private static FieldInfo _fi_pv_pWater; private static readonly Dictionary _targets = new Dictionary(); internal static void Initialize(ManualLogSource log) { _log = log; _fi_pv_pMove = AccessTools.Field(typeof(PlayerVisual), "_pMove"); _fi_pv_pWater = AccessTools.Field(typeof(PlayerVisual), "_pWater"); } internal static void Shutdown() { RemoveAllTargets(); } internal static void AddTarget(Player player, SitMode mode) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown if (!((Object)(object)player == (Object)null) && !((Object)(object)player._pVisual == (Object)null)) { PlayerVisual pVisual = player._pVisual; if (!_targets.ContainsKey(pVisual)) { TargetInfo value = new TargetInfo { Player = player, Visual = pVisual, Animator = pVisual._visualAnimator, Move = (PlayerMove)_fi_pv_pMove.GetValue(pVisual), Water = (PlayerWater)_fi_pv_pWater.GetValue(pVisual), IsForceSitting = false, Mode = mode }; _targets[pVisual] = value; _log.LogInfo((object)("Target added (" + mode.ToString() + "): " + player._nickname)); } } } internal static void RemoveTarget(Player player) { if ((Object)(object)player == (Object)null || (Object)(object)player._pVisual == (Object)null) { return; } PlayerVisual pVisual = player._pVisual; if (_targets.TryGetValue(pVisual, out var value)) { if (value.IsForceSitting) { ReleaseSitAnimation(value); } _targets.Remove(pVisual); _log.LogInfo((object)("Target removed: " + player._nickname)); } } internal static void RemoveAllTargets() { foreach (KeyValuePair target in _targets) { if (target.Value.IsForceSitting) { ReleaseSitAnimation(target.Value); } } _targets.Clear(); } internal static bool IsTarget(Player player) { if ((Object)(object)player == (Object)null || (Object)(object)player._pVisual == (Object)null) { return false; } return _targets.ContainsKey(player._pVisual); } internal static void CleanupStaleTargets() { if (_targets.Count == 0) { return; } List list = null; foreach (KeyValuePair target in _targets) { if (!ValidateTarget(target.Value)) { if (list == null) { list = new List(); } list.Add(target.Key); } } if (list != null) { for (int i = 0; i < list.Count; i++) { _targets.Remove(list[i]); } } } internal static SitMode? GetTargetMode(Player player) { if ((Object)(object)player == (Object)null || (Object)(object)player._pVisual == (Object)null) { return null; } if (_targets.TryGetValue(player._pVisual, out var value)) { return value.Mode; } return null; } internal static void OnFrameUpdate(PlayerVisual pv) { if (_targets.Count == 0 || !Object.op_Implicit((Object)(object)Player._mainPlayer) || !_targets.TryGetValue(pv, out var value)) { return; } if (!ValidateTarget(value)) { if (value.IsForceSitting) { ReleaseSitAnimation(value); } _targets.Remove(pv); } else if (ShouldForceSit(value)) { ApplySitAnimation(value); } else if (value.IsForceSitting) { ReleaseSitAnimation(value); if (value.Mode == SitMode.Soft) { _targets.Remove(pv); } } } internal static void OnRpcAnimReceived(PlayerVisual pv, string animName, float animFadeTime, int animLayer) { if (_targets.Count == 0 || !_targets.TryGetValue(pv, out var value) || !value.IsForceSitting) { return; } bool flag = false; if (animLayer == 0 && animName != "Idle" && animName != "Idle_02") { flag = true; } else if (animLayer == 3 || animLayer == 7 || animLayer == 9 || animLayer == 10 || animLayer == 12) { flag = animName != "Empty" && animName != "empty"; } else if (animLayer == 1 && animName != "Empty" && animName != "empty") { flag = true; } else if (animLayer == 8 && animName != "Empty" && animName != "empty") { flag = true; } else if (animLayer == 11) { flag = false; } if (flag) { ReleaseSitAnimation(value); if (value.Mode == SitMode.Soft) { _targets.Remove(pv); } } } private static bool ValidateTarget(TargetInfo info) { return (Object)(object)info.Player != (Object)null && (Object)(object)info.Visual != (Object)null && (Object)(object)info.Animator != (Object)null && (Object)(object)info.Move != (Object)null; } private static bool ShouldForceSit(TargetInfo info) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Invalid comparison between Unknown and I4 try { if ((int)info.Player._currentPlayerCondition != 2) { return false; } if (info.Player._bufferingStatus) { return false; } if ((int)info.Move._currentMovementAction > 0) { return false; } if (!info.Move.RayGroundCheck()) { return false; } if ((Object)(object)info.Water != (Object)null && info.Water._isInWater) { return false; } if (IsActionLayerActive(info.Animator)) { return false; } return true; } catch { return false; } } private static bool IsActionLayerActive(Animator anim) { //IL_0003: 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) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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) //IL_004c: 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_006e: 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_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) AnimatorStateInfo currentAnimatorStateInfo = anim.GetCurrentAnimatorStateInfo(3); if (!((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("Empty")) { return true; } currentAnimatorStateInfo = anim.GetCurrentAnimatorStateInfo(7); if (!((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("Empty")) { return true; } currentAnimatorStateInfo = anim.GetCurrentAnimatorStateInfo(8); if (!((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("Empty")) { return true; } currentAnimatorStateInfo = anim.GetCurrentAnimatorStateInfo(9); if (!((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("Empty")) { return true; } currentAnimatorStateInfo = anim.GetCurrentAnimatorStateInfo(10); if (!((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("Empty")) { return true; } currentAnimatorStateInfo = anim.GetCurrentAnimatorStateInfo(12); if (!((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("Empty")) { return true; } return false; } private static void ApplySitAnimation(TargetInfo info) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) Animator animator = info.Animator; if (!info.IsForceSitting) { animator.CrossFade("sit_Init", 0f, 11); animator.CrossFade("Idle", 0f, 0); info.IsForceSitting = true; return; } AnimatorStateInfo currentAnimatorStateInfo = animator.GetCurrentAnimatorStateInfo(11); if (!((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("sit_Init") && !((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("sit_Loop") && !((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("sit_Loop02")) { animator.CrossFade("sit_Init", 0f, 11); animator.CrossFade("Idle", 0f, 0); } } private static void ReleaseSitAnimation(TargetInfo info) { if (info.IsForceSitting) { if ((Object)(object)info.Animator != (Object)null) { info.Animator.CrossFade("Empty", 0.06f, 11); } info.IsForceSitting = false; } } } } namespace Eleen.Atlyss.PleaseHaveASeat.Patches { [HarmonyPatch(typeof(PlayerVisual), "OnUpdate_AnimationCondition")] internal static class AnimationUpdatePatch { [HarmonyPostfix] private static void Postfix(PlayerVisual __instance) { SeatManager.OnFrameUpdate(__instance); } } [HarmonyPatch(typeof(PlayerVisual), "UserCode_Rpc_CrossFadeAnim__String__Single__Int32")] internal static class RpcCrossFadePatch { [HarmonyPrefix] private static void Prefix(PlayerVisual __instance, string _animName, float _animFadeTime, int _animLayer) { SeatManager.OnRpcAnimReceived(__instance, _animName, _animFadeTime, _animLayer); } } [HarmonyPatch(typeof(PlayerVisual), "UserCode_IncludeRpc_Crossfade__String__Single__Int32")] internal static class IncludeRpcCrossFadePatch { [HarmonyPrefix] private static void Prefix(PlayerVisual __instance, string _animName, float _animFadeTime, int _animLayer) { SeatManager.OnRpcAnimReceived(__instance, _animName, _animFadeTime, _animLayer); } } }