using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("0.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace PeakAdminMenu { [BepInPlugin("pichau.peak.adminmenu", "Peak Admin Menu", "1.0.2")] [BepInProcess("PEAK.exe")] public sealed class PeakAdminMenuPlugin : BaseUnityPlugin { private sealed class MovementSnapshot { public float MovementForce { get; } public float SprintMultiplier { get; } public float JumpImpulse { get; } public float JumpGravity { get; } public float MaxGravity { get; } public float FallDamageTime { get; } public MovementSnapshot(CharacterMovement movement) { MovementForce = movement.movementForce; SprintMultiplier = movement.sprintMultiplier; JumpImpulse = movement.jumpImpulse; JumpGravity = movement.jumpGravity; MaxGravity = movement.maxGravity; FallDamageTime = GetFallDamageTime(movement); } public void Restore(CharacterMovement movement) { movement.movementForce = MovementForce; movement.sprintMultiplier = SprintMultiplier; movement.jumpImpulse = JumpImpulse; movement.jumpGravity = JumpGravity; movement.maxGravity = MaxGravity; SetFallDamageTime(movement, FallDamageTime); } } public const string PluginGuid = "pichau.peak.adminmenu"; public const string PluginName = "Peak Admin Menu"; public const string PluginVersion = "1.0.0"; private const string PresencePropertyKey = "peak_admin_menu"; private const string HostLockRoomPropertyKey = "peak_admin_host_lock"; private const string AutoKickRoomPropertyKey = "peak_admin_auto_kick"; private const float SelfRefreshInterval = 0.15f; private const float RoomSyncInterval = 1.25f; private const float AutoKickScanInterval = 0.75f; private const float ItemRefreshInterval = 3f; private const int MaxFeedEntries = 14; private static readonly string[] Tabs = new string[5] { "Session", "Players", "Self", "Items", "Chaos" }; private static readonly MethodInfo DropAllItemsMethod = AccessTools.Method(typeof(CharacterItems), "DropAllItems", new Type[1] { typeof(bool) }, (Type[])null); private static readonly MethodInfo SpawnItemInHandMethod = AccessTools.Method(typeof(CharacterItems), "SpawnItemInHand", new Type[1] { typeof(string) }, (Type[])null); private static readonly FieldInfo FallDamageTimeField = AccessTools.Field(typeof(CharacterMovement), "fallDamageTime"); private static readonly FieldInfo IsInvincibleField = AccessTools.Field(typeof(CharacterData), "isInvincible"); private static readonly MethodInfo RpcaReviveMethod = AccessTools.Method(typeof(Character), "RPCA_Revive", new Type[1] { typeof(bool) }, (Type[])null); private ConfigEntry _toggleKey; private ConfigEntry _hostOnlyLock; private ConfigEntry _autoKickModdedJoiners; private ConfigEntry _startMenuOpen; private bool _menuOpen; private int _selectedTab; private int _selectedActorNumber = -1; private Rect _windowRect = new Rect(48f, 48f, 980f, 720f); private Vector2 _playerScroll; private Vector2 _panelScroll; private Vector2 _itemScroll; private Vector2 _feedScroll; private float _nextSelfRefreshTime; private float _nextRoomSyncTime; private float _nextAutoKickScanTime; private float _nextItemRefreshTime; private bool _godMode; private bool _infiniteStamina; private bool _autoCleanse; private bool _noFallDamage; private bool _appliedGodMode; private float _speedMultiplier = 1f; private float _jumpMultiplier = 1f; private float _gravityMultiplier = 1f; private string _knownRoomName = string.Empty; private string _itemSearch = string.Empty; private string _manualItemName = string.Empty; private string _statusLine = "Ready."; private bool _capturedCursorState; private bool _previousCursorVisible; private CursorLockMode _previousCursorLockMode; private CharacterMovement _movementTarget; private MovementSnapshot _movementSnapshot; private readonly List _cachedItemNames = new List(); private readonly List _feedEntries = new List(); private readonly HashSet _autoKickedUsers = new HashSet(StringComparer.Ordinal); private void Awake() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) _toggleKey = ((BaseUnityPlugin)this).Config.Bind("General", "ToggleKey", new KeyboardShortcut((KeyCode)289, Array.Empty()), "Keybind for showing or hiding the admin menu."); _hostOnlyLock = ((BaseUnityPlugin)this).Config.Bind("Moderation", "HostOnlyLock", false, "When enabled, only the host gets live admin controls."); _autoKickModdedJoiners = ((BaseUnityPlugin)this).Config.Bind("Moderation", "AutoKickModdedJoiners", false, "When enabled by the host, anyone joining with this mod gets kicked automatically."); _startMenuOpen = ((BaseUnityPlugin)this).Config.Bind("General", "OpenMenuOnLaunch", false, "Open the menu when the plugin loads."); _menuOpen = _startMenuOpen.Value; if (_menuOpen) { ApplyCursorState(shouldShow: true); } AddFeed("Menu loaded. F8 toggles the overlay."); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Peak Admin Menu 1.0.0 loaded."); } private void Update() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = _toggleKey.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { _menuOpen = !_menuOpen; ApplyCursorState(_menuOpen); AddFeed(_menuOpen ? "Menu opened." : "Menu closed."); } SyncRoomState(); RefreshItemCache(); ApplySelfTweaks(); } private void OnDestroy() { RestoreMovementDefaults(); RestoreSelfState(); ApplyCursorState(shouldShow: false); } private void OnGUI() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) if (_menuOpen) { GUI.depth = 0; _windowRect = GUI.Window(814271, _windowRect, new WindowFunction(DrawWindow), "Peak Admin Menu " + BuildHeaderSuffix()); ((Rect)(ref _windowRect)).x = Mathf.Clamp(((Rect)(ref _windowRect)).x, 0f, Mathf.Max(0f, (float)Screen.width - ((Rect)(ref _windowRect)).width)); ((Rect)(ref _windowRect)).y = Mathf.Clamp(((Rect)(ref _windowRect)).y, 0f, Mathf.Max(0f, (float)Screen.height - ((Rect)(ref _windowRect)).height)); } } private void DrawWindow(int windowId) { //IL_00ca: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginVertical(Array.Empty()); DrawTopSummary(); _selectedTab = GUILayout.Toolbar(_selectedTab, Tabs, Array.Empty()); GUILayout.Space(8f); if (IsMenuLockedForThisClient()) { DrawLockedPanel(); } else { switch (_selectedTab) { case 0: DrawSessionTab(); break; case 1: DrawPlayersTab(); break; case 2: DrawSelfTab(); break; case 3: DrawItemsTab(); break; default: DrawChaosTab(); break; } } GUILayout.Space(8f); DrawFeed(); GUILayout.EndVertical(); GUI.DragWindow(new Rect(0f, 0f, 10000f, 22f)); } private void DrawTopSummary() { string text = ((!PhotonNetwork.InRoom) ? "Offline" : (PhotonNetwork.IsMasterClient ? "Host" : "Client")); string text2 = ((PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null) ? PhotonNetwork.CurrentRoom.Name : "No active room"); int num = (PhotonNetwork.InRoom ? PhotonNetwork.PlayerList.Length : 0); string text3 = (((Object)(object)RunManager.Instance != (Object)null && RunManager.Instance.timeSinceRunStarted > 0f) ? FormatSeconds(RunManager.Instance.timeSinceRunStarted) : "No run"); GUILayout.BeginVertical(GUIStyle.op_Implicit("box"), Array.Empty()); GUILayout.Label($"Role: {text} Room: {text2} Players: {num} Run: {text3}", Array.Empty()); GUILayout.Label(_statusLine, Array.Empty()); GUILayout.EndVertical(); } private void DrawLockedPanel() { GUILayout.BeginVertical(GUIStyle.op_Implicit("box"), Array.Empty()); GUILayout.Label("The host-only lock is active, so this client is in read-only mode.", Array.Empty()); bool flag = ReadBoolRoomProperty("peak_admin_host_lock"); bool flag2 = ReadBoolRoomProperty("peak_admin_auto_kick"); GUILayout.Label("Host lock published: " + (flag ? "on" : "off"), Array.Empty()); GUILayout.Label("Auto-kick for modded joiners: " + (flag2 ? "on" : "off"), Array.Empty()); GUILayout.Label("If the host enables auto-kick, clients joining with this menu will get booted by PEAK's built-in kick path.", Array.Empty()); GUILayout.EndVertical(); } private void DrawSessionTab() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) bool enabled = CanUseHostActions(); _panelScroll = GUILayout.BeginScrollView(_panelScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) }); GUILayout.BeginVertical(GUIStyle.op_Implicit("box"), Array.Empty()); GUILayout.Label("Moderation", Array.Empty()); _hostOnlyLock.Value = GUILayout.Toggle(_hostOnlyLock.Value, "Lock the full menu to the host", Array.Empty()); _autoKickModdedJoiners.Value = GUILayout.Toggle(_autoKickModdedJoiners.Value, "Kick anyone joining with this mod", Array.Empty()); GUILayout.Label("The auto-kick only works for players who also advertise this menu through Photon custom properties.", Array.Empty()); GUILayout.EndVertical(); GUILayout.BeginVertical(GUIStyle.op_Implicit("box"), Array.Empty()); GUILayout.Label("Lobby Buttons", Array.Empty()); GUILayout.BeginHorizontal(Array.Empty()); if (ActionButton("Revive Everyone", enabled)) { foreach (Character allPlayerCharacter in GetAllPlayerCharacters()) { ReviveCharacter(allPlayerCharacter); CleanseCharacter(allPlayerCharacter); } SetStatus("Everybody got picked back up."); } if (ActionButton("Cleanse Everyone", enabled)) { foreach (Character allPlayerCharacter2 in GetAllPlayerCharacters()) { CleanseCharacter(allPlayerCharacter2); } SetStatus("Everybody got scrubbed clean."); } if (ActionButton("Bring Everyone", enabled)) { BringEveryoneToLocalPlayer(); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); if (ActionButton("Scatter Everyone", enabled)) { ScatterEveryone(); } if (ActionButton("Drop Everyone's Gear", enabled)) { foreach (Character allPlayerCharacter3 in GetAllPlayerCharacters()) { DropAllItems(allPlayerCharacter3); } SetStatus("Every backpack in the lobby just had a very bad day."); } if (ActionButton("Reset My Sliders", enabled: true)) { ResetSelfTuners(); SetStatus("Speed, jump, and gravity tuners reset."); } GUILayout.EndHorizontal(); GUILayout.EndVertical(); GUILayout.BeginVertical(GUIStyle.op_Implicit("box"), Array.Empty()); GUILayout.Label("Quick Notes", Array.Empty()); GUILayout.Label("Host actions use PEAK's live character/player APIs, including the new built-in kick flow.", Array.Empty()); GUILayout.Label("Self cheats are immediate-mode toggles and mostly stay local to you unless the action explicitly hits another player.", Array.Empty()); GUILayout.Label("The silly buttons live in the Chaos tab.", Array.Empty()); GUILayout.EndVertical(); GUILayout.EndScrollView(); } private void DrawPlayersTab() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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) List list = GetOrderedPlayers().ToList(); EnsureSelectedPlayer(list); Player val = ((IEnumerable)list).FirstOrDefault((Func)((Player player) => player.ActorNumber == _selectedActorNumber)); GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) }); _playerScroll = GUILayout.BeginScrollView(_playerScroll, GUIStyle.op_Implicit("box"), (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(280f), GUILayout.ExpandHeight(true) }); foreach (Player item in list) { string text = (item.IsMasterClient ? "[HOST] " : string.Empty); string text2 = (item.IsLocal ? " [YOU]" : string.Empty); string text3 = (IsAdvertisingMenu(item) ? " [MOD]" : string.Empty); bool flag = item.ActorNumber == _selectedActorNumber; if (GUILayout.Toggle(flag, $"{text}{item.NickName}#{item.ActorNumber}{text2}{text3}", GUIStyle.op_Implicit("Button"), Array.Empty())) { _selectedActorNumber = item.ActorNumber; } } GUILayout.EndScrollView(); GUILayout.BeginVertical(GUIStyle.op_Implicit("box"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) }); if (val == null) { GUILayout.Label("No player selected.", Array.Empty()); } else { DrawSelectedPlayerPanel(val); } GUILayout.EndVertical(); GUILayout.EndHorizontal(); } private void DrawSelectedPlayerPanel(Player player) { //IL_026a: Unknown result type (might be due to invalid IL or missing references) bool flag = CanUseHostActions(); Character character; bool flag2 = TryGetCharacter(player.ActorNumber, out character); string text = ((!string.IsNullOrEmpty(player.UserId)) ? player.UserId : "No user id yet"); GUILayout.Label("Player: " + player.NickName, Array.Empty()); GUILayout.Label($"Actor: {player.ActorNumber}", Array.Empty()); GUILayout.Label("User ID: " + text, Array.Empty()); GUILayout.Label("Advertising menu: " + (IsAdvertisingMenu(player) ? "yes" : "no"), Array.Empty()); GUILayout.Label("Character ready: " + (flag2 ? "yes" : "no"), Array.Empty()); GUILayout.Space(8f); GUILayout.BeginHorizontal(Array.Empty()); if (ActionButton("Go To Player", flag2)) { TeleportLocalTo(character); } if (ActionButton("Bring To Me", flag && flag2)) { BringCharacterToLocal(character, 0f); } if (ActionButton("Respawn Them", flag && flag2)) { RespawnCharacter(character); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); if (ActionButton("Revive", flag && flag2)) { ReviveCharacter(character); SetStatus("Revived " + player.NickName + "."); } if (ActionButton("Cleanse", flag && flag2)) { CleanseCharacter(character); SetStatus("Cleansed " + player.NickName + "."); } if (ActionButton("Down", flag && flag2)) { PassOutCharacter(character); SetStatus(player.NickName + " is taking a nap."); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); if (ActionButton("Strip Gear", flag && flag2)) { DropAllItems(character); SetStatus(player.NickName + "'s inventory is now decor."); } if (ActionButton("Yeet Skyward", flag && flag2)) { LaunchCharacter(character, new Vector3(0f, 4800f, 0f)); SetStatus(player.NickName + " has achieved temporary orbit."); } if (ActionButton("Kick", flag && !player.IsLocal)) { KickPlayer(player); } GUILayout.EndHorizontal(); GUILayout.Space(12f); GUILayout.Label("The kick button uses PEAK's own host kick flow, so it behaves like the new in-game kick path.", Array.Empty()); } private void DrawSelfTab() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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_028e: Unknown result type (might be due to invalid IL or missing references) Character localCharacter = GetLocalCharacter(); bool flag = (Object)(object)localCharacter != (Object)null; _panelScroll = GUILayout.BeginScrollView(_panelScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) }); GUILayout.BeginVertical(GUIStyle.op_Implicit("box"), Array.Empty()); GUILayout.Label("Toggles", Array.Empty()); _godMode = GUILayout.Toggle(_godMode, "God mode", Array.Empty()); _infiniteStamina = GUILayout.Toggle(_infiniteStamina, "Infinite stamina", Array.Empty()); _autoCleanse = GUILayout.Toggle(_autoCleanse, "Auto-cleanse statuses", Array.Empty()); _noFallDamage = GUILayout.Toggle(_noFallDamage, "No fall damage", Array.Empty()); GUILayout.EndVertical(); GUILayout.BeginVertical(GUIStyle.op_Implicit("box"), Array.Empty()); GUILayout.Label("Tuners", Array.Empty()); DrawSlider("Speed", ref _speedMultiplier, 0.5f, 4.5f); DrawSlider("Jump", ref _jumpMultiplier, 0.5f, 4.5f); DrawSlider("Gravity", ref _gravityMultiplier, 0.2f, 2f); GUILayout.Label("Lower gravity gets floaty fast. If movement feels weird, hit Reset My Sliders in the Session tab.", Array.Empty()); GUILayout.EndVertical(); GUILayout.BeginVertical(GUIStyle.op_Implicit("box"), Array.Empty()); GUILayout.Label("Buttons", Array.Empty()); GUILayout.BeginHorizontal(Array.Empty()); if (ActionButton("Become Host (MasterClient)", PhotonNetwork.InRoom)) { PhotonNetwork.SetMasterClient(PhotonNetwork.LocalPlayer); SetStatus("Tried to become MasterClient."); } if (ActionButton("Revive Me", flag)) { ReviveCharacter(localCharacter); CleanseCharacter(localCharacter); SetStatus("Back in business."); } if (ActionButton("Respawn Me", flag)) { RespawnCharacter(localCharacter); SetStatus("Warped back to spawn."); } if (ActionButton("Cleanse Me", flag)) { CleanseCharacter(localCharacter); SetStatus("All the bad stuff got washed off."); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); if (ActionButton("Drop My Gear", flag)) { DropAllItems(localCharacter); SetStatus("You are now traveling light."); } if (ActionButton("Tiny Yeet", flag)) { LaunchCharacter(localCharacter, new Vector3(0f, 2200f, 0f)); SetStatus("Boing."); } if (ActionButton("Random Gift", flag && _cachedItemNames.Count > 0)) { string itemName = _cachedItemNames[Random.Range(0, _cachedItemNames.Count)]; SpawnLocalItem(itemName, 1); } GUILayout.EndHorizontal(); GUILayout.EndVertical(); GUILayout.EndScrollView(); } private void DrawItemsTab() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) Character localCharacter = GetLocalCharacter(); bool flag = (Object)(object)localCharacter != (Object)null; _panelScroll = GUILayout.BeginScrollView(_panelScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) }); GUILayout.BeginVertical(GUIStyle.op_Implicit("box"), Array.Empty()); GUILayout.Label("Spawner", Array.Empty()); GUILayout.Label("Search", Array.Empty()); _itemSearch = GUILayout.TextField(_itemSearch ?? string.Empty, Array.Empty()); GUILayout.Label("Exact item name", Array.Empty()); _manualItemName = GUILayout.TextField(_manualItemName ?? string.Empty, Array.Empty()); GUILayout.BeginHorizontal(Array.Empty()); if (ActionButton("Spawn In Hand", flag && !string.IsNullOrWhiteSpace(_manualItemName))) { SpawnLocalItem(_manualItemName, 1); } if (ActionButton("Spawn 5", flag && !string.IsNullOrWhiteSpace(_manualItemName))) { SpawnLocalItem(_manualItemName, 5); } if (ActionButton("Refresh Item List", enabled: true)) { ForceRefreshItemCache(); SetStatus($"Found {_cachedItemNames.Count} item names."); } GUILayout.EndHorizontal(); GUILayout.EndVertical(); GUILayout.BeginVertical(GUIStyle.op_Implicit("box"), Array.Empty()); GUILayout.Label("Matching Items", Array.Empty()); _itemScroll = GUILayout.BeginScrollView(_itemScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(360f) }); IEnumerable source = _cachedItemNames.Where((string name) => string.IsNullOrWhiteSpace(_itemSearch) || name.IndexOf(_itemSearch, StringComparison.OrdinalIgnoreCase) >= 0); int num = 0; foreach (string item in source.Take(80)) { if (GUILayout.Button(item, Array.Empty())) { _manualItemName = item; } num++; } if (num == 0) { GUILayout.Label("No matches yet.", Array.Empty()); } GUILayout.EndScrollView(); GUILayout.EndVertical(); GUILayout.EndScrollView(); } private void DrawChaosTab() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) bool enabled = CanUseHostActions(); Character localCharacter = GetLocalCharacter(); bool enabled2 = (Object)(object)localCharacter != (Object)null; _panelScroll = GUILayout.BeginScrollView(_panelScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) }); GUILayout.BeginVertical(GUIStyle.op_Implicit("box"), Array.Empty()); GUILayout.Label("Panic Buttons", Array.Empty()); GUILayout.BeginHorizontal(Array.Empty()); if (ActionButton("Panic Rescue", enabled)) { foreach (Character allPlayerCharacter in GetAllPlayerCharacters()) { ReviveCharacter(allPlayerCharacter); CleanseCharacter(allPlayerCharacter); } BringEveryoneToLocalPlayer(); SetStatus("Emergency cuddle pile initiated."); } if (ActionButton("Bounce House", enabled)) { Vector3 force = default(Vector3); foreach (Character allPlayerCharacter2 in GetAllPlayerCharacters()) { ((Vector3)(ref force))..ctor(Random.Range(-1800f, 1800f), Random.Range(2200f, 4200f), Random.Range(-1800f, 1800f)); LaunchCharacter(allPlayerCharacter2, force); } SetStatus("The lobby has become a trampoline park."); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); if (ActionButton("Lobby Laundry Day", enabled)) { foreach (Character allPlayerCharacter3 in GetAllPlayerCharacters()) { DropAllItems(allPlayerCharacter3); } SetStatus("Loose items everywhere."); } if (ActionButton("Solo Rocket Jump", enabled2)) { LaunchCharacter(localCharacter, new Vector3(0f, 6500f, 0f)); SetStatus("Do not ask physics to explain that."); } GUILayout.EndHorizontal(); GUILayout.EndVertical(); GUILayout.BeginVertical(GUIStyle.op_Implicit("box"), Array.Empty()); GUILayout.Label("Useful Weirdness", Array.Empty()); GUILayout.Label("Panic Rescue: revives and cleanses everybody, then pulls them near you.", Array.Empty()); GUILayout.Label("Bounce House: launches every player with a randomized force.", Array.Empty()); GUILayout.Label("Lobby Laundry Day: forces all player inventories to spill out.", Array.Empty()); GUILayout.EndVertical(); GUILayout.EndScrollView(); } private void DrawFeed() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginVertical(GUIStyle.op_Implicit("box"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(140f) }); GUILayout.Label("Feed", Array.Empty()); _feedScroll = GUILayout.BeginScrollView(_feedScroll, Array.Empty()); foreach (string feedEntry in _feedEntries) { GUILayout.Label(feedEntry, Array.Empty()); } GUILayout.EndScrollView(); GUILayout.EndVertical(); } private void SyncRoomState() { string text = ((PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null) ? PhotonNetwork.CurrentRoom.Name : string.Empty); if (!string.Equals(text, _knownRoomName, StringComparison.Ordinal)) { _knownRoomName = text; _autoKickedUsers.Clear(); if (!PhotonNetwork.InRoom) { _selectedActorNumber = -1; } } if (!(Time.unscaledTime < _nextRoomSyncTime)) { _nextRoomSyncTime = Time.unscaledTime + 1.25f; PublishPresenceProperty(); PublishRoomFlags(); if (ShouldAutoKickJoiners()) { ScanForModdedJoiners(); } } } private void PublishPresenceProperty() { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown if (PhotonNetwork.InRoom && PhotonNetwork.LocalPlayer != null && (PhotonNetwork.LocalPlayer.CustomProperties == null || !((Dictionary)(object)PhotonNetwork.LocalPlayer.CustomProperties).TryGetValue((object)"peak_admin_menu", out object value) || !string.Equals(Convert.ToString(value), "1.0.0", StringComparison.Ordinal))) { Hashtable val = new Hashtable { [(object)"peak_admin_menu"] = "1.0.0" }; PhotonNetwork.LocalPlayer.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); } } private void PublishRoomFlags() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown if (PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient && PhotonNetwork.CurrentRoom != null) { Hashtable val = new Hashtable { [(object)"peak_admin_host_lock"] = _hostOnlyLock.Value, [(object)"peak_admin_auto_kick"] = _autoKickModdedJoiners.Value }; PhotonNetwork.CurrentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); } } private bool ShouldAutoKickJoiners() { return PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient && _autoKickModdedJoiners.Value; } private void ScanForModdedJoiners() { if (Time.unscaledTime < _nextAutoKickScanTime) { return; } _nextAutoKickScanTime = Time.unscaledTime + 0.75f; Player[] playerListOthers = PhotonNetwork.PlayerListOthers; Player val2 = default(Player); foreach (Player val in playerListOthers) { if (IsAdvertisingMenu(val)) { string item = BuildUserKey(val); if (!_autoKickedUsers.Contains(item) && PlayerHandler.TryGetPlayer(val.ActorNumber, ref val2) && !((Object)(object)val2 == (Object)null)) { PlayerHandler.Kick(val.ActorNumber); _autoKickedUsers.Add(item); AddFeed("Host-lock kicked " + val.NickName + " for joining with Peak Admin Menu."); } } } } private void RefreshItemCache() { if (!(Time.unscaledTime < _nextItemRefreshTime)) { _nextItemRefreshTime = Time.unscaledTime + 3f; ForceRefreshItemCache(); } } private void ForceRefreshItemCache() { Item[] array = Resources.FindObjectsOfTypeAll(); if (array != null && array.Length != 0) { _cachedItemNames.Clear(); _cachedItemNames.AddRange((from item in array select ((Object)(object)item != (Object)null) ? ((Object)item).name.Replace("(Clone)", string.Empty).Trim() : string.Empty into name where !string.IsNullOrWhiteSpace(name) select name).Distinct(StringComparer.OrdinalIgnoreCase).OrderBy((string name) => name, StringComparer.OrdinalIgnoreCase)); if (string.IsNullOrWhiteSpace(_manualItemName) && _cachedItemNames.Count > 0) { _manualItemName = _cachedItemNames[0]; } } } private void ApplySelfTweaks() { Character localCharacter = GetLocalCharacter(); if ((Object)(object)localCharacter == (Object)null) { RestoreMovementDefaults(); return; } ApplyMovementTuning(localCharacter); if (_godMode || _autoCleanse || _infiniteStamina) { if (!(Time.unscaledTime >= _nextSelfRefreshTime)) { return; } _nextSelfRefreshTime = Time.unscaledTime + 0.15f; if (_godMode) { SetInvincible(localCharacter.data, value: true); _appliedGodMode = true; if (localCharacter.data.dead || localCharacter.data.passedOut || localCharacter.data.fullyPassedOut) { Character.Revive(); } } if (_autoCleanse || _godMode) { CleanseCharacter(localCharacter); } if (_infiniteStamina || _godMode) { Character.GainFullStamina(); } } else { RestoreSelfState(); } } private void ApplyMovementTuning(Character localCharacter) { CharacterMovement val = ((localCharacter.refs != null) ? localCharacter.refs.movement : null); if ((Object)(object)val == (Object)null) { RestoreMovementDefaults(); return; } if (_movementTarget != val) { RestoreMovementDefaults(); _movementTarget = val; _movementSnapshot = new MovementSnapshot(val); } if (_movementSnapshot != null) { val.movementForce = _movementSnapshot.MovementForce * _speedMultiplier; val.sprintMultiplier = _movementSnapshot.SprintMultiplier * Mathf.Max(1f, _speedMultiplier); val.jumpImpulse = _movementSnapshot.JumpImpulse * _jumpMultiplier; val.jumpGravity = _movementSnapshot.JumpGravity * _gravityMultiplier; val.maxGravity = _movementSnapshot.MaxGravity * _gravityMultiplier; SetFallDamageTime(val, _noFallDamage ? 99999f : _movementSnapshot.FallDamageTime); } } private void RestoreMovementDefaults() { if ((Object)(object)_movementTarget != (Object)null && _movementSnapshot != null) { _movementSnapshot.Restore(_movementTarget); } _movementTarget = null; _movementSnapshot = null; } private void RestoreSelfState() { Character localCharacter = GetLocalCharacter(); if ((Object)(object)localCharacter == (Object)null) { _appliedGodMode = false; } else if (_appliedGodMode) { SetInvincible(localCharacter.data, value: false); localCharacter.data.RecalculateInvincibility(); _appliedGodMode = false; } } private void BringEveryoneToLocalPlayer() { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: 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) Character localCharacter = GetLocalCharacter(); if ((Object)(object)localCharacter == (Object)null) { SetStatus("Need a live local character first."); return; } List list = (from character in GetAllPlayerCharacters() where (Object)(object)character != (Object)null && !character.IsLocal select character).ToList(); if (list.Count == 0) { SetStatus("Nobody else is around to drag over."); return; } for (int num = 0; num < list.Count; num++) { float num2 = (float)num * (MathF.PI * 2f / (float)Mathf.Max(1, list.Count)); float num3 = 2f + (float)(num % 2) * 0.75f; Vector3 val = new Vector3(Mathf.Cos(num2), 0.25f, Mathf.Sin(num2)) * num3; WarpCharacter(list[num], localCharacter.Center + val); } SetStatus("Everybody has been reeled back in."); } private void ScatterEveryone() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) Vector3 force = default(Vector3); foreach (Character allPlayerCharacter in GetAllPlayerCharacters()) { ((Vector3)(ref force))..ctor(Random.Range(-2200f, 2200f), Random.Range(1800f, 4200f), Random.Range(-2200f, 2200f)); LaunchCharacter(allPlayerCharacter, force); } SetStatus("Scatter command sent."); } private void KickPlayer(Player player) { Player val = default(Player); if (!PlayerHandler.TryGetPlayer(player.ActorNumber, ref val)) { SetStatus(player.NickName + " is not fully registered yet."); return; } if ((Object)(object)val == (Object)null) { SetStatus(player.NickName + " is not fully registered yet."); return; } PlayerHandler.Kick(player.ActorNumber); SetStatus("Kicked " + player.NickName + "."); } private void TeleportLocalTo(Character target) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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_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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) Character localCharacter = GetLocalCharacter(); if ((Object)(object)localCharacter == (Object)null || (Object)(object)target == (Object)null) { SetStatus("Teleport needs both characters ready."); return; } Vector3 position = target.Center + ((Component)target).transform.forward * -2f + Vector3.up * 0.25f; WarpCharacter(localCharacter, position); SetStatus("Teleported to " + target.characterName + "."); } private void BringCharacterToLocal(Character target, float lateralOffset) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: 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_0067: Unknown result type (might be due to invalid IL or missing references) Character localCharacter = GetLocalCharacter(); if ((Object)(object)localCharacter == (Object)null || (Object)(object)target == (Object)null) { SetStatus("Bring needs both characters ready."); return; } Vector3 position = localCharacter.Center + ((Component)localCharacter).transform.right * lateralOffset + ((Component)localCharacter).transform.forward * 2f; WarpCharacter(target, position); SetStatus("Dragged " + target.characterName + " over."); } private void RespawnCharacter(Character target) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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_0062: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null) { return; } if (target.IsLocal) { Character.WarpToSpawn(); return; } Transform val = (((Object)(object)target.data != (Object)null) ? target.data.spawnPoint : null); if ((Object)(object)val != (Object)null) { WarpCharacter(target, val.position + Vector3.up * 0.15f); } } private void ReviveCharacter(Character target) { if (!((Object)(object)target == (Object)null)) { if (target.IsLocal) { Character.Revive(); } else if (target.refs != null && (Object)(object)target.refs.view != (Object)null) { target.refs.view.RPC("RPCA_Revive", (RpcTarget)0, new object[1] { false }); } else if (RpcaReviveMethod != null) { RpcaReviveMethod.Invoke(target, new object[1] { false }); } } } private void PassOutCharacter(Character target) { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)target == (Object)null)) { if (target.IsLocal) { Character.PassOut(); } else if (target.refs != null && (Object)(object)target.refs.view != (Object)null) { target.refs.view.RPC("RPCA_PassOut", (RpcTarget)0, Array.Empty()); } else { target.RPCA_PassOut(default(PhotonMessageInfo)); } } } private void CleanseCharacter(Character target) { if (!((Object)(object)target == (Object)null)) { if (target.refs != null && (Object)(object)target.refs.afflictions != (Object)null) { target.refs.afflictions.ClearAllStatus(false); target.refs.afflictions.ClearAllAfflictions(); target.refs.afflictions.PushStatuses((Player)null); target.refs.afflictions.PushAfflictions((Player)null); } if ((Object)(object)target.data != (Object)null) { target.data.currentStamina = target.GetMaxStamina(); } } } private void LaunchCharacter(Character target, Vector3 force) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)target == (Object)null)) { Vector3 center = target.Center; if (target.refs != null && (Object)(object)target.refs.view != (Object)null) { target.refs.view.RPC("RPCA_AddForceAtPosition", (RpcTarget)0, new object[3] { force, center, 7f }); } else { target.RPCA_AddForceAtPosition(force, center, 7f, default(PhotonMessageInfo)); } } } private void WarpCharacter(Character target, Vector3 position) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0068: 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_0049: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)target == (Object)null)) { if (target.refs != null && (Object)(object)target.refs.view != (Object)null) { target.refs.view.RPC("WarpPlayerRPC", (RpcTarget)0, new object[2] { position, true }); } else { target.WarpPlayerRPC(position, true, default(PhotonMessageInfo)); } } } private void DropAllItems(Character target) { if (!((Object)(object)target == (Object)null) && target.refs != null && !((Object)(object)target.refs.items == (Object)null) && DropAllItemsMethod != null) { DropAllItemsMethod.Invoke(target.refs.items, new object[1] { true }); } } private void SpawnLocalItem(string itemName, int amount) { Character localCharacter = GetLocalCharacter(); if ((Object)(object)localCharacter == (Object)null || localCharacter.refs == null || (Object)(object)localCharacter.refs.items == (Object)null) { SetStatus("Need a local character before spawning items."); return; } if (string.IsNullOrWhiteSpace(itemName)) { SetStatus("Pick an item name first."); return; } if (_cachedItemNames.Count > 0 && !_cachedItemNames.Contains(itemName, StringComparer.OrdinalIgnoreCase)) { SetStatus("'" + itemName + "' was not found in the cached item list."); return; } for (int i = 0; i < amount; i++) { SpawnItemInHandMethod?.Invoke(localCharacter.refs.items, new object[1] { itemName }); } SetStatus($"Spawned {amount}x {itemName}."); } private Character GetLocalCharacter() { object obj = Character.localCharacter; if (obj == null) { Player localPlayer = Player.localPlayer; obj = ((localPlayer != null) ? localPlayer.character : null); } return (Character)obj; } private IEnumerable GetAllPlayerCharacters() { return from character in PlayerHandler.GetAllPlayerCharacters() where (Object)(object)character != (Object)null select character; } private bool TryGetCharacter(int actorNumber, out Character character) { return PlayerHandler.TryGetCharacter(actorNumber, ref character); } private IEnumerable GetOrderedPlayers() { IEnumerable result; if (!PhotonNetwork.InRoom) { result = Enumerable.Empty(); } else { IEnumerable enumerable = from player in PhotonNetwork.PlayerList orderby player.IsMasterClient descending, player.ActorNumber select player; result = enumerable; } return result; } private void EnsureSelectedPlayer(IReadOnlyCollection players) { if (players.Count == 0) { _selectedActorNumber = -1; } else if (!players.Any((Player player) => player.ActorNumber == _selectedActorNumber)) { _selectedActorNumber = players.First().ActorNumber; } } private bool IsMenuLockedForThisClient() { return _hostOnlyLock.Value && PhotonNetwork.InRoom && !PhotonNetwork.IsMasterClient; } private bool CanUseHostActions() { return PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient; } private bool IsAdvertisingMenu(Player player) { if (player == null || player.CustomProperties == null) { return false; } return ((Dictionary)(object)player.CustomProperties).ContainsKey((object)"peak_admin_menu"); } private bool ReadBoolRoomProperty(string key) { if (!PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null || ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties == null) { return false; } if (!((Dictionary)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)key, out object value)) { return false; } bool flag = default(bool); int num; if (value is bool) { flag = (bool)value; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } private string BuildUserKey(Player player) { return (!string.IsNullOrEmpty(player.UserId)) ? player.UserId : $"actor:{player.ActorNumber}"; } private string BuildHeaderSuffix() { if (!PhotonNetwork.InRoom) { return "Offline"; } return PhotonNetwork.IsMasterClient ? "Host Controls" : "Client View"; } private void ResetSelfTuners() { _speedMultiplier = 1f; _jumpMultiplier = 1f; _gravityMultiplier = 1f; _noFallDamage = false; } private static float GetFallDamageTime(CharacterMovement movement) { if ((Object)(object)movement == (Object)null || FallDamageTimeField == null) { return 0f; } return (FallDamageTimeField.GetValue(movement) is float num) ? num : 0f; } private static void SetFallDamageTime(CharacterMovement movement, float value) { if ((Object)(object)movement != (Object)null && FallDamageTimeField != null) { FallDamageTimeField.SetValue(movement, value); } } private static void SetInvincible(CharacterData data, bool value) { if ((Object)(object)data != (Object)null && IsInvincibleField != null) { IsInvincibleField.SetValue(data, value); } } private void ApplyCursorState(bool shouldShow) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (shouldShow) { if (!_capturedCursorState) { _previousCursorVisible = Cursor.visible; _previousCursorLockMode = Cursor.lockState; _capturedCursorState = true; } Cursor.visible = true; Cursor.lockState = (CursorLockMode)0; } else if (_capturedCursorState) { Cursor.visible = _previousCursorVisible; Cursor.lockState = _previousCursorLockMode; _capturedCursorState = false; } } private void DrawSlider(string label, ref float value, float min, float max) { GUILayout.Label($"{label}: {value:0.00}", Array.Empty()); value = GUILayout.HorizontalSlider(value, min, max, Array.Empty()); } private bool ActionButton(string label, bool enabled) { bool enabled2 = GUI.enabled; GUI.enabled = enabled; bool result = GUILayout.Button(label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MinHeight(28f) }); GUI.enabled = enabled2; return result; } private void SetStatus(string message) { _statusLine = message; AddFeed(message); } private void AddFeed(string message) { string item = $"[{DateTime.Now:HH:mm:ss}] {message}"; _feedEntries.Add(item); if (_feedEntries.Count > 14) { _feedEntries.RemoveAt(0); } _feedScroll.y = float.MaxValue; ((BaseUnityPlugin)this).Logger.LogInfo((object)message); } private string FormatSeconds(float totalSeconds) { TimeSpan timeSpan = TimeSpan.FromSeconds(Math.Max(0f, totalSeconds)); return (timeSpan.TotalHours >= 1.0) ? timeSpan.ToString("hh\\:mm\\:ss") : timeSpan.ToString("mm\\:ss"); } } }