Decompiled source of CubeX v3.6.0

plugins/CubeX.dll

Decompiled 15 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using BepInEx;
using CubeX.Core;
using CubeX.Features;
using CubeX.Features.Actions;
using CubeX.Features.Game;
using CubeX.Features.Host;
using CubeX.Features.Inventory;
using CubeX.Features.Items.Extra_Slot;
using CubeX.Features.Items.Slot_1.Assign_Item;
using CubeX.Features.Items.Slot_2.Assign_Item;
using CubeX.Features.Items.Slot_3.Assign_Item;
using CubeX.Features.Items.Slot_4___Backpack;
using CubeX.Features.Misc;
using CubeX.Features.Misc.Discord_Community;
using CubeX.Features.Misc.PauseMenuFeatures;
using CubeX.Features.Misc.Startup;
using CubeX.Features.Network;
using CubeX.Features.Network.Blacklist;
using CubeX.Features.Network.Friends;
using CubeX.Features.Network.Players.Steam;
using CubeX.Features.Network.Recent_Players;
using CubeX.Features.Performance;
using CubeX.Features.Performance.Frame_Rate;
using CubeX.Features.Performance.Rendering;
using CubeX.Features.Player;
using CubeX.Features.Player.PlayerActions;
using CubeX.Features.Search;
using CubeX.Features.Self;
using CubeX.Features.Self.Camera;
using CubeX.Features.Self.Camera.Zoom;
using CubeX.Features.Self.Free_Cam;
using CubeX.Features.Self.Glider;
using CubeX.Features.Self.Items.Charges;
using CubeX.Features.Self.Local_Safety;
using CubeX.Features.Self.Miscellaneous;
using CubeX.Features.Self.Miscellaneous.Aura_Farm_Item;
using CubeX.Features.Self.Movement.Collision;
using CubeX.Features.Self.Movement.Flight___NoClip;
using CubeX.Features.Self.Movement.Multipliers;
using CubeX.Features.Self.Movement.Stamina___Jump;
using CubeX.Features.Self.Protections;
using CubeX.Features.Settings;
using CubeX.Features.Settings.HUD___UI;
using CubeX.Features.Spawn;
using CubeX.Features.Spawn.Guns;
using CubeX.Features.Spawn.Item_Tools;
using CubeX.Features.Spawn.Items;
using CubeX.Features.Spawn.Items.Item_Selector;
using CubeX.Features.Teleport;
using CubeX.Features.Teleport.CampfireLocations;
using CubeX.Features.Teleport.Current_Biome_Start;
using CubeX.Features.Teleport.Important_Locations;
using CubeX.Features.Teleport.Important_Locations.Scene_Campfires;
using CubeX.Features.Teleport.Saved_Coordinates;
using CubeX.Features.Visuals;
using CubeX.Features.Visuals.Awareness;
using CubeX.Features.Visuals.ESP.Colors;
using CubeX.Features.Visuals.ESP.Layers;
using CubeX.Features.Visuals.ESP.Targets;
using CubeX.Features.Visuals.ESP_Limits;
using CubeX.Features.Visuals.Footsteps;
using CubeX.Features.Visuals.Lava;
using CubeX.Features.Visuals.Profile_Cards;
using CubeX.Features.Visuals.Rope;
using CubeX.Features.Visuals.Trails;
using CubeX.Features.Visuals.World_Tags;
using CubeX.Features.World;
using CubeX.Features.World.Luggage;
using CubeX.Patches.Misc;
using CubeX.Runtime.Diagnostics;
using CubeX.Runtime.Lifecycle;
using CubeX.Runtime.Misc;
using CubeX.Runtime.Network;
using CubeX.Runtime.Performance;
using CubeX.Runtime.Player;
using CubeX.Runtime.Self;
using CubeX.Runtime.Teleport;
using CubeX.Runtime.Visuals;
using CubeX.Runtime.World;
using CubeX.UI;
using CubeX.UI.Features;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Peak;
using Peak.Afflictions;
using Peak.Island;
using Peak.Network;
using Peak.UI;
using Photon.Pun;
using Photon.Realtime;
using Photon.Voice;
using Photon.Voice.PUN;
using Photon.Voice.Unity;
using Portningsbolaget;
using Portningsbolaget.Photon;
using Portningsbolaget.Platforms;
using Portningsbolaget.Utilities;
using Steamworks;
using TMPro;
using Unity.Collections;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Zorro.Core;
using Zorro.Core.Serizalization;
using Zorro.Settings;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("CubeX")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("3.6.0.0")]
[assembly: AssemblyInformationalVersion("3.6.0+5f73d0e371c9d2f7cde27a03f16efc6aea42f29f")]
[assembly: AssemblyProduct("Cube-X mod menu for PEAK")]
[assembly: AssemblyTitle("CubeX")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("3.6.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[DebuggerDisplay("Count = {System.Collections.ICollection.Count}")]
[CompilerGenerated]
internal sealed class <>z__ReadOnlyArray<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
	int ICollection.Count => _items.Length;

	bool ICollection.IsSynchronized => false;

	object ICollection.SyncRoot => this;

	object IList.this[int index]
	{
		get
		{
			return _items[index];
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	bool IList.IsFixedSize => true;

	bool IList.IsReadOnly => true;

	int IReadOnlyCollection<T>.Count => _items.Length;

	T IReadOnlyList<T>.this[int index] => _items[index];

	int ICollection<T>.Count => _items.Length;

	bool ICollection<T>.IsReadOnly => true;

	T IList<T>.this[int index]
	{
		get
		{
			return _items[index];
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	public <>z__ReadOnlyArray(T[] items)
	{
		_items = items;
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return ((IEnumerable)_items).GetEnumerator();
	}

	void ICollection.CopyTo(Array array, int index)
	{
		((ICollection)_items).CopyTo(array, index);
	}

	int IList.Add(object value)
	{
		throw new NotSupportedException();
	}

	void IList.Clear()
	{
		throw new NotSupportedException();
	}

	bool IList.Contains(object value)
	{
		return ((IList)_items).Contains(value);
	}

	int IList.IndexOf(object value)
	{
		return ((IList)_items).IndexOf(value);
	}

	void IList.Insert(int index, object value)
	{
		throw new NotSupportedException();
	}

	void IList.Remove(object value)
	{
		throw new NotSupportedException();
	}

	void IList.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}

	IEnumerator<T> IEnumerable<T>.GetEnumerator()
	{
		return ((IEnumerable<T>)_items).GetEnumerator();
	}

	void ICollection<T>.Add(T item)
	{
		throw new NotSupportedException();
	}

	void ICollection<T>.Clear()
	{
		throw new NotSupportedException();
	}

	bool ICollection<T>.Contains(T item)
	{
		return ((ICollection<T>)_items).Contains(item);
	}

	void ICollection<T>.CopyTo(T[] array, int arrayIndex)
	{
		((ICollection<T>)_items).CopyTo(array, arrayIndex);
	}

	bool ICollection<T>.Remove(T item)
	{
		throw new NotSupportedException();
	}

	int IList<T>.IndexOf(T item)
	{
		return ((IList<T>)_items).IndexOf(item);
	}

	void IList<T>.Insert(int index, T item)
	{
		throw new NotSupportedException();
	}

	void IList<T>.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}
}
[DebuggerDisplay("Count = {System.Collections.ICollection.Count}")]
[CompilerGenerated]
internal sealed class <>z__ReadOnlyList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
	int ICollection.Count => _items.Count;

	bool ICollection.IsSynchronized => false;

	object ICollection.SyncRoot => this;

	object IList.this[int index]
	{
		get
		{
			return _items[index];
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	bool IList.IsFixedSize => true;

	bool IList.IsReadOnly => true;

	int IReadOnlyCollection<T>.Count => _items.Count;

	T IReadOnlyList<T>.this[int index] => _items[index];

	int ICollection<T>.Count => _items.Count;

	bool ICollection<T>.IsReadOnly => true;

	T IList<T>.this[int index]
	{
		get
		{
			return _items[index];
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	public <>z__ReadOnlyList(List<T> items)
	{
		_items = items;
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return ((IEnumerable)_items).GetEnumerator();
	}

	void ICollection.CopyTo(Array array, int index)
	{
		((ICollection)_items).CopyTo(array, index);
	}

	int IList.Add(object value)
	{
		throw new NotSupportedException();
	}

	void IList.Clear()
	{
		throw new NotSupportedException();
	}

	bool IList.Contains(object value)
	{
		return ((IList)_items).Contains(value);
	}

	int IList.IndexOf(object value)
	{
		return ((IList)_items).IndexOf(value);
	}

	void IList.Insert(int index, object value)
	{
		throw new NotSupportedException();
	}

	void IList.Remove(object value)
	{
		throw new NotSupportedException();
	}

	void IList.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}

	IEnumerator<T> IEnumerable<T>.GetEnumerator()
	{
		return ((IEnumerable<T>)_items).GetEnumerator();
	}

	void ICollection<T>.Add(T item)
	{
		throw new NotSupportedException();
	}

	void ICollection<T>.Clear()
	{
		throw new NotSupportedException();
	}

	bool ICollection<T>.Contains(T item)
	{
		return _items.Contains(item);
	}

	void ICollection<T>.CopyTo(T[] array, int arrayIndex)
	{
		_items.CopyTo(array, arrayIndex);
	}

	bool ICollection<T>.Remove(T item)
	{
		throw new NotSupportedException();
	}

	int IList<T>.IndexOf(T item)
	{
		return _items.IndexOf(item);
	}

	void IList<T>.Insert(int index, T item)
	{
		throw new NotSupportedException();
	}

	void IList<T>.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}
}
[DebuggerDisplay("Count = {System.Collections.ICollection.Count}")]
[CompilerGenerated]
internal sealed class <>z__ReadOnlySingleElementList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
	private sealed class Enumerator : IDisposable, IEnumerator, IEnumerator<T>
	{
		object IEnumerator.Current => _item;

		T IEnumerator<T>.Current => _item;

		public Enumerator(T item)
		{
			_item = item;
		}

		bool IEnumerator.MoveNext()
		{
			if (!_moveNextCalled)
			{
				return _moveNextCalled = true;
			}
			return false;
		}

		void IEnumerator.Reset()
		{
			_moveNextCalled = false;
		}

		void IDisposable.Dispose()
		{
		}
	}

	int ICollection.Count => 1;

	bool ICollection.IsSynchronized => false;

	object ICollection.SyncRoot => this;

	object IList.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	bool IList.IsFixedSize => true;

	bool IList.IsReadOnly => true;

	int IReadOnlyCollection<T>.Count => 1;

	T IReadOnlyList<T>.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
	}

	int ICollection<T>.Count => 1;

	bool ICollection<T>.IsReadOnly => true;

	T IList<T>.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	public <>z__ReadOnlySingleElementList(T item)
	{
		_item = item;
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return new Enumerator(_item);
	}

	void ICollection.CopyTo(Array array, int index)
	{
		array.SetValue(_item, index);
	}

	int IList.Add(object value)
	{
		throw new NotSupportedException();
	}

	void IList.Clear()
	{
		throw new NotSupportedException();
	}

	bool IList.Contains(object value)
	{
		return EqualityComparer<T>.Default.Equals(_item, (T)value);
	}

	int IList.IndexOf(object value)
	{
		if (!EqualityComparer<T>.Default.Equals(_item, (T)value))
		{
			return -1;
		}
		return 0;
	}

	void IList.Insert(int index, object value)
	{
		throw new NotSupportedException();
	}

	void IList.Remove(object value)
	{
		throw new NotSupportedException();
	}

	void IList.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}

	IEnumerator<T> IEnumerable<T>.GetEnumerator()
	{
		return new Enumerator(_item);
	}

	void ICollection<T>.Add(T item)
	{
		throw new NotSupportedException();
	}

	void ICollection<T>.Clear()
	{
		throw new NotSupportedException();
	}

	bool ICollection<T>.Contains(T item)
	{
		return EqualityComparer<T>.Default.Equals(_item, item);
	}

	void ICollection<T>.CopyTo(T[] array, int arrayIndex)
	{
		array[arrayIndex] = _item;
	}

	bool ICollection<T>.Remove(T item)
	{
		throw new NotSupportedException();
	}

	int IList<T>.IndexOf(T item)
	{
		if (!EqualityComparer<T>.Default.Equals(_item, item))
		{
			return -1;
		}
		return 0;
	}

	void IList<T>.Insert(int index, T item)
	{
		throw new NotSupportedException();
	}

	void IList<T>.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}
}
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;
		}
	}
}
public class ZoomiesKey : TextFeature
{
	public override string KeybindId => "CubeX.Features.Visuals.ZoomiesKey";

	public ZoomiesKey()
	{
		base.Name = "Zoom Key";
		base.Description = "Key held for camera zoom. Examples: C, Mouse1, LeftAlt.";
		base.MaxLength = 24;
		SetText(((object)Unsafe.As<KeyCode, KeyCode>(ref ZoomiesHoldZoom.HoldKey)/*cast due to .constrained prefix*/).ToString());
	}

	protected override void OnTextChanged(string newValue)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		if (Enum.TryParse<KeyCode>(newValue, ignoreCase: true, out KeyCode result) && (int)result != 0)
		{
			ZoomiesHoldZoom.HoldKey = result;
		}
	}
}
namespace CubeX
{
	[BepInPlugin("com.mister9982.cubex", "Cube-X", "3.6.0")]
	public sealed class BepInExPlugin : BaseUnityPlugin
	{
		private Plugin _runtime;

		private void Awake()
		{
			bool num = Object.op_Implicit((Object)(object)Plugin.Instance) && Plugin.Instance.IsInitialized;
			Plugin runtime = RuntimeStartup.Start(new CubeXLog((Action<object>)((BaseUnityPlugin)this).Logger.LogInfo, (Action<object>)((BaseUnityPlugin)this).Logger.LogWarning, (Action<object>)((BaseUnityPlugin)this).Logger.LogError, (Action<object>)((BaseUnityPlugin)this).Logger.LogDebug), "BepInEx");
			if (!num)
			{
				_runtime = runtime;
			}
		}

		private void OnDestroy()
		{
			if (Object.op_Implicit((Object)(object)_runtime))
			{
				Object.Destroy((Object)(object)((Component)_runtime).gameObject);
			}
		}
	}
	public sealed class CubeXLog
	{
		private readonly Action<object> _info;

		private readonly Action<object> _warning;

		private readonly Action<object> _error;

		private readonly Action<object> _debug;

		public CubeXLog(Action<object> info = null, Action<object> warning = null, Action<object> error = null, Action<object> debug = null)
		{
			_info = info;
			_warning = warning;
			_error = error;
			_debug = debug;
		}

		public void LogInfo(object message)
		{
			Write("Info", message, _info);
		}

		public void LogWarning(object message)
		{
			Write("Warning", message, _warning);
		}

		public void LogError(object message)
		{
			Write("Error", message, _error);
		}

		public void LogDebug(object message)
		{
			Write("Debug", message, _debug);
		}

		private void Write(string level, object message, Action<object> sink)
		{
			if (sink != null)
			{
				sink(message);
				return;
			}
			string text = "[Cube-X " + level + "] " + message;
			if (level == "Error")
			{
				Debug.LogError((object)text);
			}
			else if (level == "Warning")
			{
				Debug.LogWarning((object)text);
			}
			else
			{
				Debug.Log((object)text);
			}
		}
	}
	internal static class RuntimeStartup
	{
		internal static Plugin Start(CubeXLog log, string mode)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			Assembly own = typeof(RuntimeStartup).Assembly;
			if (AppDomain.CurrentDomain.GetAssemblies().Any((Assembly assembly) => assembly != own && assembly.GetName().Name == own.GetName().Name))
			{
				log.LogError("Another Cube-X assembly is already loaded. Restart PEAK to change versions.");
				return null;
			}
			if (Object.op_Implicit((Object)(object)Plugin.Instance) && Plugin.Instance.IsInitialized)
			{
				return Plugin.Instance;
			}
			Plugin.Log = log;
			GameObject val = null;
			try
			{
				val = new GameObject("Cube-X");
				Object.DontDestroyOnLoad((Object)(object)val);
				Plugin plugin = val.AddComponent<Plugin>();
				if (!plugin.IsInitialized)
				{
					throw plugin.StartupError ?? new InvalidOperationException("Cube-X did not initialize.");
				}
				return plugin;
			}
			catch (Exception ex)
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					Object.Destroy((Object)(object)val);
				}
				log.LogError("Startup failed: " + ex);
				return null;
			}
		}
	}
	public class Plugin : MonoBehaviour
	{
		[HarmonyPatch(typeof(Quicksave), "TryLoadSave")]
		internal static class QuicksaveTryLoadSavePatch
		{
			private static bool Prefix(Action<bool> onLoaded)
			{
				if (Quicksave.Exists)
				{
					return true;
				}
				onLoaded?.Invoke(obj: false);
				return false;
			}
		}

		private const BindingFlags HarmonyMethodFlags = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

		private readonly OwnedComponents _components = new OwnedComponents();

		private Harmony _harmony;

		private int _lastTickFrame = -1;

		private bool _shuttingDown;

		private bool _updateFailureLogged;

		private const string ModGuid = "com.mister9982.cubex";

		private const string ModName = "Cube-X";

		public const string ModVersion = "3.6.0";

		public const string ModDisplayVersion = "3.6.0";

		public static Plugin Instance { get; private set; }

		public static CubeXLog Log { get; internal set; } = new CubeXLog();

		internal bool IsInitialized { get; private set; }

		internal Exception StartupError { get; private set; }

		private static FeatureManager FeatureManager { get; set; }

		private static MenuUI Menu { get; set; }

		internal static MenuUI MenuUi => Menu;

		private void Awake()
		{
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Expected O, but got Unknown
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)Instance) && (Object)(object)Instance != (Object)(object)this)
			{
				((Behaviour)this).enabled = false;
				Object.Destroy((Object)(object)this);
				return;
			}
			Instance = this;
			try
			{
				FeatureManager = new FeatureManager();
				FeatureManager.RegisterAllFromAssembly();
				ConfigService.Initialize(FeatureManager);
				AfflictionRateSettings.Initialize();
				ProtectionSettings.Initialize();
				Menu = _components.Track(((Component)this).gameObject.AddComponent<MenuUI>());
				Menu.Bind(FeatureManager, new SelectedPlayerPreviewPanel());
				_components.Track<GameEventNotifier>(((Component)this).gameObject.AddComponent<GameEventNotifier>());
				NotificationSystem.MarkReady();
				_harmony = new Harmony("com.mister9982.cubex");
				PatchAllSafely();
				Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
				IsInitialized = true;
				CubeXDiagnostics.Info("Cube-X", string.Format("v{0} loaded - press {1} to open.", "3.6.0", RuntimeKeybinds.MenuBind), notify: true);
			}
			catch (Exception ex)
			{
				Exception exception = (StartupError = ex);
				CubeXDiagnostics.Error("Cube-X", "Startup failed.", exception);
				Shutdown();
			}
		}

		private void Update()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (!IsInitialized)
			{
				return;
			}
			try
			{
				MenuInputCapture.Tick();
				if (!RuntimeKeybinds.BlocksGlobalHotkeys && Object.op_Implicit((Object)(object)Menu))
				{
					bool keyDown = Input.GetKeyDown(RuntimeKeybinds.MenuBind);
					bool flag = MenuControllerInput.ToggleMenuPressed();
					if (keyDown || flag)
					{
						Menu.IsOpen = !Menu.IsOpen;
					}
				}
			}
			catch (Exception exception)
			{
				LogTickFailure("Update loop failed. Further update-loop errors will be logged only.", "Update loop failed.", exception);
			}
		}

		private void FixedUpdate()
		{
			if (!IsInitialized)
			{
				return;
			}
			try
			{
				FeatureManager?.FixedTick();
			}
			catch (Exception exception)
			{
				LogTickFailure("Fixed tick failed. Further fixed-tick errors will be logged only.", "Fixed tick failed.", exception);
			}
		}

		private void LateUpdate()
		{
			if (!IsInitialized)
			{
				return;
			}
			int frameCount = Time.frameCount;
			if (_lastTickFrame == frameCount)
			{
				return;
			}
			_lastTickFrame = frameCount;
			try
			{
				MenuInputCapture.Tick();
				RuntimeKeybinds.TickFeatureBinds(FeatureManager);
				CharacterColliderSuppression.Tick();
				FeatureManager?.Tick();
				ConfigService.Tick();
				MenuInputCapture.Tick();
			}
			catch (Exception exception)
			{
				LogTickFailure("Frame tick failed. Further frame-tick errors will be logged only.", "Frame tick failed.", exception);
			}
		}

		private void OnDestroy()
		{
			Shutdown();
		}

		private void Shutdown()
		{
			if (_shuttingDown || (Object)(object)Instance != (Object)(object)this)
			{
				return;
			}
			_shuttingDown = true;
			IsInitialized = false;
			((Behaviour)this).enabled = false;
			CubeXDiagnostics.Try("Cube-X", "Cancel teleport item recovery", NonHostTeleportTest.Reset, notifyErrors: false);
			CubeXDiagnostics.Try("Cube-X", "Shutdown config", ConfigService.Shutdown, notifyErrors: false);
			CubeXDiagnostics.Try("Cube-X", "Disable features", delegate
			{
				FeatureManager?.DisableAll();
			}, notifyErrors: false);
			CubeXDiagnostics.Try("Cube-X", "Shutdown menu", delegate
			{
				Menu?.Shutdown();
			}, notifyErrors: false);
			CubeXDiagnostics.Try("Cube-X", "Release native ESP", PlayerEsp.Shutdown, notifyErrors: false);
			CubeXDiagnostics.Try("Cube-X", "Restore carry camera zoom", PiggybackCarrySpectateSelectionPatch.RestoreZoom, notifyErrors: false);
			CubeXDiagnostics.Try("Cube-X", "Release pause avatars", PauseMenuPlayerAvatar.DisposeAll, notifyErrors: false);
			CubeXDiagnostics.Try("Cube-X", "Release platform icons", PlayerPlatformIcons.Dispose, notifyErrors: false);
			CubeXDiagnostics.Try("Cube-X", "Stop owned components", _components.Dispose, notifyErrors: false);
			CubeXDiagnostics.Try("Cube-X", "Unpatch Harmony", delegate
			{
				Harmony harmony = _harmony;
				if (harmony != null)
				{
					harmony.UnpatchSelf();
				}
			}, notifyErrors: false);
			CubeXDiagnostics.Try("Cube-X", "Release input", MenuInputCapture.EndAll, notifyErrors: false);
			CubeXDiagnostics.Try("Cube-X", "Shutdown keybinds", RuntimeKeybinds.Shutdown, notifyErrors: false);
			CubeXDiagnostics.Try("Cube-X", "Shutdown notifications", NotificationSystem.Shutdown, notifyErrors: false);
			CubeXDiagnostics.Try("Cube-X", "Flush protection log", ProtectionLog.Close, notifyErrors: false);
			_harmony = null;
			Menu = null;
			FeatureManager = null;
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}

		private void PatchAllSafely()
		{
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			int num4 = 0;
			Type[] typesSafely = GetTypesSafely(Assembly.GetExecutingAssembly());
			foreach (Type type in typesSafely)
			{
				if (type == null || !HasHarmonyPatch(type))
				{
					continue;
				}
				try
				{
					int num5 = _harmony.CreateClassProcessor(type).Patch()?.Count ?? 0;
					if (num5 > 0)
					{
						num++;
						num2 += num5;
					}
					else
					{
						num3++;
					}
				}
				catch (Exception ex)
				{
					num4++;
					CubeXDiagnostics.Warning("Harmony", "Failed patch " + type.FullName + ": " + ex.GetBaseException().Message);
				}
			}
			CubeXDiagnostics.Info("Harmony", $"Patch classes active: {num}, methods patched: {num2}, " + $"inactive/no-target: {num3}, failed: {num4}.", num3 > 0 || num4 > 0);
		}

		private static Type[] GetTypesSafely(Assembly assembly)
		{
			try
			{
				return assembly.GetTypes();
			}
			catch (ReflectionTypeLoadException ex)
			{
				return ex.Types.Where((Type type) => type != null).ToArray();
			}
		}

		private static bool HasHarmonyPatch(Type type)
		{
			if (type.IsDefined(typeof(HarmonyPatch), inherit: false))
			{
				return true;
			}
			MethodInfo[] methods = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			for (int i = 0; i < methods.Length; i++)
			{
				if (methods[i].IsDefined(typeof(HarmonyPatch), inherit: false))
				{
					return true;
				}
			}
			return false;
		}

		private void LogTickFailure(string firstMessage, string repeatedMessage, Exception exception)
		{
			bool flag = !_updateFailureLogged;
			if (flag)
			{
				_updateFailureLogged = true;
			}
			CubeXDiagnostics.Error("Cube-X", flag ? firstMessage : repeatedMessage, exception, flag);
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "CubeX";

		public const string PLUGIN_NAME = "Cube-X mod menu for PEAK";

		public const string PLUGIN_VERSION = "3.6.0";
	}
	internal static class CubeXBuildIdentity
	{
		public const bool IsDeveloperBuild = false;

		public const string Name = "User";
	}
}
namespace CubeX.UI
{
	[HarmonyPatch(typeof(Character), "RPCA_Die")]
	internal static class CharacterDiedNotificationPatch
	{
		private static void Postfix(Character __instance)
		{
			CharacterEventNotifications.NotifyDied(__instance, RpcSenderContext.Current);
		}
	}
	[HarmonyPatch(typeof(Character), "RPCA_PassOut")]
	internal static class CharacterPassedOutNotificationPatch
	{
		private static void Postfix(Character __instance)
		{
			CharacterEventNotifications.NotifyPassedOut(__instance, RpcSenderContext.Current);
		}
	}
	[HarmonyPatch(typeof(Character), "RPCA_ReviveAtPosition")]
	internal static class CharacterRevivedAtPositionNotificationPatch
	{
		private static void Postfix(Character __instance)
		{
			CharacterEventNotifications.NotifyRevived(__instance, RpcSenderContext.Current);
		}
	}
	[HarmonyPatch(typeof(Character), "ReviveCharacter")]
	internal static class CharacterRevivedNotificationPatch
	{
		private static void Postfix(Character __instance)
		{
			CharacterEventNotifications.NotifyRevived(__instance, RpcSenderContext.Current);
		}
	}
	internal sealed class SelectedPlayerPreviewPanel : ISelectedPlayerPreviewPanel, IDisposable
	{
		private const int TextureWidth = 384;

		private const int TextureHeight = 512;

		private const int InventorySlotCount = 4;

		private const int CarriedItemSlotCount = 3;

		private const float RenderInterval = 1f / 12f;

		private const float MissingReferenceRetryInterval = 0.5f;

		private const float MissingCameraRetryInterval = 1f;

		private const float InventorySignatureInterval = 0.2f;

		private static readonly Color BackgroundColor = new Color(0.015f, 0.016f, 0.018f, 1f);

		private static readonly Renderer[] NoRenderers = Array.Empty<Renderer>();

		private static readonly int VertexGhost = Shader.PropertyToID("_VertexGhost");

		private readonly Texture[] _inventoryIcons = (Texture[])(object)new Texture[4];

		private readonly bool[] _inventoryOccupied = new bool[4];

		private readonly Item[] _observedInventoryPrefabs = (Item[])(object)new Item[3];

		private Camera _camera;

		private Character _character;

		private Renderer[] _eyeRenderers = NoRenderers;

		private PlayerGhost _ghost;

		private bool _inventoryDirty = true;

		private int _lastReferenceCheckFrame = -1;

		private PlayerDirectory.SelectedPlayerInfo _lastSelectionSnapshot;

		private Camera _mainCamera;

		private Renderer _mouthRenderer;

		private float _nextCameraRetryAt;

		private float _nextInventorySignatureAt;

		private float _nextReferenceRetryAt;

		private float _nextRenderAt;

		private bool _observedBackpack;

		private MaterialPropertyBlock[] _originalRendererBlocks = Array.Empty<MaterialPropertyBlock>();

		private Player _player;

		private MaterialPropertyBlock[] _previewRendererBlocks = Array.Empty<MaterialPropertyBlock>();

		private Transform _previewRoot;

		private bool _renderCallbacksSubscribed;

		private Renderer[] _renderers = NoRenderers;

		private GameObject _root;

		private int _sceneHandle = int.MinValue;

		private int _selectedActorNumber = -1;

		private string _selectedPlayerId;

		private RenderTexture _target;

		private bool _targetCleared = true;

		private bool[] _temporarilyEnabledRenderers = Array.Empty<bool>();

		private bool[] _temporarilyOverriddenRenderers = Array.Empty<bool>();

		private bool _usingGhost;

		private bool _visible;

		public bool SupportsInventory => true;

		public bool HasPreview
		{
			get
			{
				RefreshCachedReferences();
				return !string.IsNullOrEmpty(_selectedPlayerId);
			}
		}

		public Texture GetTexture()
		{
			SetVisible(visible: true);
			EnsureResources();
			RefreshCachedReferences();
			if (!Object.op_Implicit((Object)(object)_previewRoot) && !_targetCleared)
			{
				ClearTarget();
			}
			return (Texture)(object)_target;
		}

		public bool IsInventorySlotOccupied(int slotIndex)
		{
			if (slotIndex < 0 || slotIndex >= 4)
			{
				return false;
			}
			RefreshCachedReferences();
			RefreshInventoryIfNeeded();
			return _inventoryOccupied[slotIndex];
		}

		public Texture GetInventorySlotIcon(int slotIndex)
		{
			if (slotIndex < 0 || slotIndex >= 4)
			{
				return null;
			}
			RefreshCachedReferences();
			RefreshInventoryIfNeeded();
			Texture val = _inventoryIcons[slotIndex];
			if (!Object.op_Implicit((Object)(object)val))
			{
				return null;
			}
			return val;
		}

		public void Tick()
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			RestoreTemporarilyEnabledRenderers();
			if (Object.op_Implicit((Object)(object)_camera) && ((Behaviour)_camera).enabled)
			{
				((Behaviour)_camera).enabled = false;
			}
			if (!_visible)
			{
				return;
			}
			EnsureResources();
			RefreshCachedReferences();
			RefreshInventoryIfNeeded();
			if (!Object.op_Implicit((Object)(object)_camera))
			{
				return;
			}
			float unscaledTime = Time.unscaledTime;
			if (unscaledTime < _nextRenderAt)
			{
				return;
			}
			if (!TryGetRendererBounds(out var bounds))
			{
				_nextRenderAt = unscaledTime + 0.5f;
				if (!_targetCleared)
				{
					ClearTarget();
				}
			}
			else
			{
				ConfigureCamera(bounds);
				((Behaviour)_camera).enabled = true;
				_targetCleared = false;
				_nextRenderAt = unscaledTime + 1f / 12f;
			}
		}

		public void SetVisible(bool visible)
		{
			if (_visible == visible)
			{
				return;
			}
			_visible = visible;
			if (!visible)
			{
				RestoreTemporarilyEnabledRenderers();
				if (Object.op_Implicit((Object)(object)_camera))
				{
					((Behaviour)_camera).enabled = false;
				}
				_nextRenderAt = 0f;
			}
		}

		public void Dispose()
		{
			RestoreTemporarilyEnabledRenderers();
			BindPlayer(null);
			if (_renderCallbacksSubscribed)
			{
				RenderPipelineManager.beginCameraRendering -= OnBeginCameraRendering;
				RenderPipelineManager.endCameraRendering -= OnEndCameraRendering;
				_renderCallbacksSubscribed = false;
			}
			if (Object.op_Implicit((Object)(object)_camera))
			{
				((Behaviour)_camera).enabled = false;
			}
			if (Object.op_Implicit((Object)(object)_target))
			{
				_target.Release();
				Object.Destroy((Object)(object)_target);
				_target = null;
			}
			if (Object.op_Implicit((Object)(object)_root))
			{
				Object.Destroy((Object)(object)_root);
				_root = null;
			}
			_camera = null;
			_mainCamera = null;
			ClearVisualTarget();
		}

		private void EnsureResources()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)_root))
			{
				_root = new GameObject("CubeX Selected Player Live Preview")
				{
					hideFlags = (HideFlags)61
				};
				Object.DontDestroyOnLoad((Object)(object)_root);
				_camera = _root.AddComponent<Camera>();
				((Behaviour)_camera).enabled = false;
				_camera.clearFlags = (CameraClearFlags)2;
				_camera.backgroundColor = BackgroundColor;
				_camera.orthographic = true;
				_camera.nearClipPlane = 0.02f;
				_camera.farClipPlane = 18f;
				_camera.allowHDR = false;
				_camera.allowMSAA = false;
				_camera.useOcclusionCulling = false;
				_camera.depthTextureMode = (DepthTextureMode)0;
				_camera.renderingPath = (RenderingPath)1;
				_camera.depth = -100f;
			}
			if (!_renderCallbacksSubscribed)
			{
				RenderPipelineManager.beginCameraRendering += OnBeginCameraRendering;
				RenderPipelineManager.endCameraRendering += OnEndCameraRendering;
				_renderCallbacksSubscribed = true;
			}
			if (!Object.op_Implicit((Object)(object)_target))
			{
				_target = new RenderTexture(384, 512, 16, (RenderTextureFormat)0)
				{
					hideFlags = (HideFlags)61,
					filterMode = (FilterMode)1,
					wrapMode = (TextureWrapMode)1,
					antiAliasing = 1,
					useMipMap = false,
					autoGenerateMips = false
				};
				_target.Create();
				ClearTarget();
			}
			else if (!_target.IsCreated())
			{
				_target.Create();
				ClearTarget();
			}
			if (Object.op_Implicit((Object)(object)_camera) && (Object)(object)_camera.targetTexture != (Object)(object)_target)
			{
				_camera.targetTexture = _target;
			}
		}

		private void RefreshCachedReferences()
		{
			RefreshSceneState();
			PlayerDirectory.SelectedPlayerInfo selectedPlayer = PlayerDirectory.SelectedPlayer;
			int frameCount = Time.frameCount;
			if (_lastReferenceCheckFrame == frameCount && _lastSelectionSnapshot == selectedPlayer)
			{
				return;
			}
			_lastReferenceCheckFrame = frameCount;
			_lastSelectionSnapshot = selectedPlayer;
			string text = selectedPlayer?.Id;
			int num = ParseActorNumber(selectedPlayer?.ActorText);
			Player player = null;
			Character character = null;
			if (selectedPlayer != null)
			{
				if (num > 0)
				{
					TryGetRegisteredPlayerAndCharacter(num, out player, out character);
				}
				else
				{
					character = selectedPlayer.Character;
					if (!Object.op_Implicit((Object)(object)character))
					{
						character = null;
					}
					player = TryGetCharacterPlayer(character);
				}
			}
			bool num2 = !string.Equals(_selectedPlayerId, text, StringComparison.Ordinal) || _selectedActorNumber != num;
			bool flag = _character != character;
			bool flag2 = _player != player;
			if (num2 || flag)
			{
				_selectedPlayerId = text;
				_selectedActorNumber = num;
				_character = character;
				BindPlayer(player);
				RefreshVisualTarget(force: true);
				return;
			}
			if (flag2)
			{
				BindPlayer(player);
			}
			RefreshVisualTarget(force: false);
			if ((!Object.op_Implicit((Object)(object)_player) || !Object.op_Implicit((Object)(object)_previewRoot)) && Time.unscaledTime >= _nextReferenceRetryAt)
			{
				_nextReferenceRetryAt = Time.unscaledTime + 0.5f;
				if (!Object.op_Implicit((Object)(object)_player) && Object.op_Implicit((Object)(object)_character))
				{
					BindPlayer(TryGetCharacterPlayer(_character));
				}
				if (Object.op_Implicit((Object)(object)_previewRoot) && RendererCacheNeedsRefresh())
				{
					CacheRendererReferences();
				}
			}
		}

		private unsafe void RefreshSceneState()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			int num = (((Scene)(ref activeScene)).IsValid() ? ((object)(*(Scene*)(&activeScene))/*cast due to .constrained prefix*/).GetHashCode() : int.MinValue);
			if (num != _sceneHandle)
			{
				_sceneHandle = num;
				_mainCamera = null;
				_nextCameraRetryAt = 0f;
				_lastReferenceCheckFrame = -1;
				_lastSelectionSnapshot = null;
				_selectedPlayerId = null;
				_selectedActorNumber = -1;
				_character = null;
				BindPlayer(null);
				ClearVisualTarget();
			}
		}

		private void RefreshVisualTarget(bool force)
		{
			Character character = _character;
			if (!Object.op_Implicit((Object)(object)character) || !Object.op_Implicit((Object)(object)((Component)character).gameObject) || !((Component)character).gameObject.activeInHierarchy)
			{
				if (force || Object.op_Implicit((Object)(object)_previewRoot) || Object.op_Implicit((Object)(object)_ghost))
				{
					ClearVisualTarget();
				}
				return;
			}
			CharacterData data = character.data;
			bool flag = data != null && data.dead;
			PlayerGhost val = (flag ? character.Ghost : null);
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)((Component)val).gameObject) || !((Component)val).gameObject.activeInHierarchy)
			{
				val = null;
			}
			bool flag2 = flag && Object.op_Implicit((Object)(object)val);
			Transform val2 = (flag2 ? ((Component)val).transform : ((!flag) ? GetCharacterPreviewRoot(character) : null));
			if (!Object.op_Implicit((Object)(object)val2))
			{
				val2 = null;
			}
			if (force || _usingGhost != flag2 || _ghost != val || _previewRoot != val2 || RendererCacheNeedsRefresh())
			{
				RestoreTemporarilyEnabledRenderers();
				_usingGhost = flag2;
				_ghost = val;
				_previewRoot = val2;
				CacheFaceRenderers();
				CacheRendererReferences();
				ResolveMainCamera(force: true);
				_nextRenderAt = 0f;
				if (!_targetCleared)
				{
					ClearTarget();
				}
			}
		}

		private void ClearVisualTarget()
		{
			RestoreTemporarilyEnabledRenderers();
			_ghost = null;
			_previewRoot = null;
			_renderers = NoRenderers;
			_temporarilyEnabledRenderers = Array.Empty<bool>();
			_temporarilyOverriddenRenderers = Array.Empty<bool>();
			_originalRendererBlocks = Array.Empty<MaterialPropertyBlock>();
			_previewRendererBlocks = Array.Empty<MaterialPropertyBlock>();
			_mouthRenderer = null;
			_eyeRenderers = NoRenderers;
			_usingGhost = false;
			_nextRenderAt = 0f;
			if (Object.op_Implicit((Object)(object)_camera))
			{
				((Behaviour)_camera).enabled = false;
			}
			if (!_targetCleared)
			{
				ClearTarget();
			}
		}

		private void CacheRendererReferences()
		{
			_renderers = (Object.op_Implicit((Object)(object)_previewRoot) ? ((Component)_previewRoot).GetComponentsInChildren<Renderer>(true) : NoRenderers);
			_temporarilyEnabledRenderers = ((_renderers.Length != 0) ? new bool[_renderers.Length] : Array.Empty<bool>());
			_temporarilyOverriddenRenderers = ((_renderers.Length != 0) ? new bool[_renderers.Length] : Array.Empty<bool>());
			_originalRendererBlocks = Array.Empty<MaterialPropertyBlock>();
			_previewRendererBlocks = Array.Empty<MaterialPropertyBlock>();
			if (_renderers.Length == 0)
			{
				_nextReferenceRetryAt = Time.unscaledTime + 0.5f;
			}
		}

		private bool RendererCacheNeedsRefresh()
		{
			if (!Object.op_Implicit((Object)(object)_previewRoot))
			{
				return _renderers.Length != 0;
			}
			if (_renderers == null || _renderers.Length == 0)
			{
				return Time.unscaledTime >= _nextReferenceRetryAt;
			}
			Renderer[] renderers = _renderers;
			for (int i = 0; i < renderers.Length; i++)
			{
				if (!Object.op_Implicit((Object)(object)renderers[i]))
				{
					return true;
				}
			}
			return false;
		}

		private void CacheFaceRenderers()
		{
			_mouthRenderer = null;
			_eyeRenderers = NoRenderers;
			if (_usingGhost && Object.op_Implicit((Object)(object)_ghost))
			{
				_mouthRenderer = _ghost.mouthRenderer;
				_eyeRenderers = _ghost.EyeRenderers ?? NoRenderers;
				return;
			}
			Character character = _character;
			CustomizationRefs val = ((Object.op_Implicit((Object)(object)character) && Object.op_Implicit((Object)(object)character.refs?.customization)) ? character.refs.customization.refs : null);
			if (Object.op_Implicit((Object)(object)val))
			{
				_mouthRenderer = val.mouthRenderer;
				_eyeRenderers = val.EyeRenderers ?? NoRenderers;
			}
		}

		private void BindPlayer(Player player)
		{
			if (_player == player)
			{
				return;
			}
			if (_player != null)
			{
				try
				{
					Player player2 = _player;
					player2.itemsChangedAction = (Action<ItemSlot[]>)Delegate.Remove(player2.itemsChangedAction, new Action<ItemSlot[]>(OnInventoryChanged));
				}
				catch
				{
				}
			}
			_player = player;
			if (Object.op_Implicit((Object)(object)_player))
			{
				try
				{
					Player player3 = _player;
					player3.itemsChangedAction = (Action<ItemSlot[]>)Delegate.Combine(player3.itemsChangedAction, new Action<ItemSlot[]>(OnInventoryChanged));
				}
				catch
				{
				}
			}
			ClearInventorySnapshot();
		}

		private void OnInventoryChanged(ItemSlot[] _)
		{
			_inventoryDirty = true;
		}

		private void RefreshInventoryIfNeeded()
		{
			float unscaledTime = Time.unscaledTime;
			if (!_inventoryDirty && unscaledTime < _nextInventorySignatureAt)
			{
				return;
			}
			_nextInventorySignatureAt = unscaledTime + 0.2f;
			bool flag = HasBackpack(_player);
			bool flag2 = _inventoryDirty || flag != _observedBackpack;
			for (int i = 0; i < 3; i++)
			{
				if (GetInventoryPrefab(_player, i) != _observedInventoryPrefabs[i])
				{
					flag2 = true;
				}
				Texture val = _inventoryIcons[i];
				if (val != null && !Object.op_Implicit((Object)(object)val))
				{
					flag2 = true;
				}
			}
			Texture val2 = _inventoryIcons[3];
			if (flag && (val2 == null || !Object.op_Implicit((Object)(object)val2)))
			{
				flag2 = true;
			}
			if (flag2)
			{
				for (int j = 0; j < 3; j++)
				{
					Item inventoryPrefab = GetInventoryPrefab(_player, j);
					_observedInventoryPrefabs[j] = inventoryPrefab;
					_inventoryOccupied[j] = Object.op_Implicit((Object)(object)inventoryPrefab);
					_inventoryIcons[j] = (Object.op_Implicit((Object)(object)inventoryPrefab) ? GetItemIcon(inventoryPrefab) : null);
				}
				_observedBackpack = flag;
				_inventoryOccupied[3] = flag;
				_inventoryIcons[3] = (flag ? GetBackpackIcon(_player) : null);
				_inventoryDirty = false;
			}
		}

		private void ClearInventorySnapshot()
		{
			Array.Clear(_observedInventoryPrefabs, 0, _observedInventoryPrefabs.Length);
			Array.Clear(_inventoryIcons, 0, _inventoryIcons.Length);
			Array.Clear(_inventoryOccupied, 0, _inventoryOccupied.Length);
			_observedBackpack = false;
			_inventoryDirty = true;
			_nextInventorySignatureAt = 0f;
		}

		private static Item GetInventoryPrefab(Player player, int index)
		{
			try
			{
				if (!Object.op_Implicit((Object)(object)player) || player.itemSlots == null || index < 0 || index >= player.itemSlots.Length)
				{
					return null;
				}
				ItemSlot val = player.itemSlots[index];
				if (val == null || val.IsEmpty())
				{
					return null;
				}
				Item prefab = val.prefab;
				return Object.op_Implicit((Object)(object)prefab) ? prefab : null;
			}
			catch
			{
				return null;
			}
		}

		private static bool HasBackpack(Player player)
		{
			try
			{
				return Object.op_Implicit((Object)(object)player) && player.backpackSlot != null && !((ItemSlot)player.backpackSlot).IsEmpty();
			}
			catch
			{
				return false;
			}
		}

		private static Texture GetBackpackIcon(Player player)
		{
			try
			{
				ItemSlot val = (ItemSlot)(object)(Object.op_Implicit((Object)(object)player) ? player.backpackSlot : null);
				Item val2 = ((val != null) ? val.prefab : null);
				if (!Object.op_Implicit((Object)(object)val2))
				{
					val2 = GameActions.LoadItemPrefab(((val != null) ? val.GetPrefabName() : null) ?? "Backpack");
				}
				return Object.op_Implicit((Object)(object)val2) ? GetItemIcon(val2) : null;
			}
			catch
			{
				return null;
			}
		}

		private static Texture GetItemIcon(Item item)
		{
			if (!Object.op_Implicit((Object)(object)item))
			{
				return null;
			}
			try
			{
				ItemUIData uIData = item.UIData;
				Texture val = (Texture)(object)((uIData != null) ? uIData.GetIcon() : null);
				if (Object.op_Implicit((Object)(object)val))
				{
					return val;
				}
			}
			catch
			{
			}
			try
			{
				Texture val2 = (Texture)(object)item.UIData?.icon;
				return Object.op_Implicit((Object)(object)val2) ? val2 : null;
			}
			catch
			{
				return null;
			}
		}

		private bool TryGetRendererBounds(out Bounds bounds)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			bounds = default(Bounds);
			if (!Object.op_Implicit((Object)(object)_previewRoot) || _renderers == null || _renderers.Length == 0)
			{
				return false;
			}
			bool allowDisabled = ShouldTemporarilyRevealGhost();
			bool flag = false;
			Renderer[] renderers = _renderers;
			foreach (Renderer val in renderers)
			{
				if (ShouldUseRenderer(val, allowDisabled))
				{
					if (!flag)
					{
						bounds = val.bounds;
						flag = true;
					}
					else
					{
						((Bounds)(ref bounds)).Encapsulate(val.bounds);
					}
				}
			}
			if (flag)
			{
				Vector3 size = ((Bounds)(ref bounds)).size;
				return ((Vector3)(ref size)).sqrMagnitude > 0.0001f;
			}
			return false;
		}

		private void ConfigureCamera(Bounds bounds)
		{
			//IL_003c: 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)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: 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)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			Camera val = ResolveMainCamera(force: false);
			_camera.cullingMask = ((Object.op_Implicit((Object)(object)val) && (Object)(object)val != (Object)(object)_camera) ? (val.cullingMask & -33) : (-33));
			_camera.backgroundColor = BackgroundColor;
			Vector3 center = ((Bounds)(ref bounds)).center;
			float num = Mathf.Max(0.75f, ((Bounds)(ref bounds)).size.y);
			float num2 = Mathf.Max(0.45f, ((Bounds)(ref bounds)).size.x);
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(center.x, ((Bounds)(ref bounds)).min.y + num * 0.52f, center.z);
			Vector3 frontViewDirection = GetFrontViewDirection(center, val);
			float num3 = Mathf.Clamp(num * 1.3f, 1.5f, 4f);
			Vector3 val3 = val2 + frontViewDirection * num3 + Vector3.up * (num * 0.02f);
			_camera.orthographic = true;
			((Component)_camera).transform.position = val3;
			((Component)_camera).transform.rotation = Quaternion.LookRotation(val2 - val3, Vector3.up);
			float num4 = Mathf.Max(0.45f, num * 0.53f);
			float num5 = Mathf.Max(0.45f, num2 / Mathf.Max(0.1f, 0.75f) * 0.68f);
			_camera.orthographicSize = Mathf.Max(num4, num5);
			_camera.nearClipPlane = 0.02f;
			_camera.farClipPlane = Mathf.Max(8f, num3 + 8f);
		}

		private Vector3 GetFrontViewDirection(Vector3 bodyCenter, Camera main)
		{
			//IL_0001: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: 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_00a4: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			if (!TryGetFaceDirection(bodyCenter, out var direction))
			{
				direction = ((!Object.op_Implicit((Object)(object)_previewRoot)) ? Vector3.forward : (_usingGhost ? _previewRoot.forward : (-_previewRoot.forward)));
			}
			direction = Vector3.ProjectOnPlane(direction, Vector3.up);
			if (((Vector3)(ref direction)).sqrMagnitude < 0.0001f)
			{
				direction = (Object.op_Implicit((Object)(object)main) ? Vector3.ProjectOnPlane(-((Component)main).transform.forward, Vector3.up) : Vector3.forward);
				if (((Vector3)(ref direction)).sqrMagnitude < 0.0001f)
				{
					direction = Vector3.forward;
				}
			}
			((Vector3)(ref direction)).Normalize();
			return direction;
		}

		private bool TryGetFaceDirection(Vector3 bodyCenter, out Vector3 direction)
		{
			//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_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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_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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			direction = Vector3.zero;
			Vector3 center = Vector3.zero;
			int count = 0;
			bool allowDisabled = ShouldTemporarilyRevealGhost();
			AddRendererCenter(_mouthRenderer, allowDisabled, ref center, ref count);
			Renderer[] eyeRenderers = _eyeRenderers;
			for (int i = 0; i < eyeRenderers.Length; i++)
			{
				AddRendererCenter(eyeRenderers[i], allowDisabled, ref center, ref count);
			}
			if (count <= 0)
			{
				return false;
			}
			center /= (float)count;
			Vector3 val = ((!_usingGhost && Object.op_Implicit((Object)(object)_character) && IsFinite(_character.Head)) ? _character.Head : bodyCenter);
			direction = Vector3.ProjectOnPlane(center - val, Vector3.up);
			return ((Vector3)(ref direction)).sqrMagnitude > 0.0001f;
		}

		private static void AddRendererCenter(Renderer renderer, bool allowDisabled, ref Vector3 center, ref int count)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (ShouldUseRenderer(renderer, allowDisabled))
			{
				Vector3 val = center;
				Bounds bounds = renderer.bounds;
				center = val + ((Bounds)(ref bounds)).center;
				count++;
			}
		}

		private static bool ShouldUseRenderer(Renderer renderer, bool allowDisabled)
		{
			if (!Object.op_Implicit((Object)(object)renderer) || !Object.op_Implicit((Object)(object)((Component)renderer).gameObject) || !((Component)renderer).gameObject.activeInHierarchy)
			{
				return false;
			}
			if (!allowDisabled && !renderer.enabled)
			{
				return false;
			}
			Type type = ((object)renderer).GetType();
			if (type == typeof(ParticleSystemRenderer) || type == typeof(LineRenderer) || type == typeof(TrailRenderer))
			{
				return false;
			}
			string obj = ((Object)renderer).name ?? string.Empty;
			string text = ((Object)((Component)renderer).gameObject).name ?? string.Empty;
			if (obj.IndexOf("shadow", StringComparison.OrdinalIgnoreCase) < 0)
			{
				return text.IndexOf("shadow", StringComparison.OrdinalIgnoreCase) < 0;
			}
			return false;
		}

		private Camera ResolveMainCamera(bool force)
		{
			if (!force && Object.op_Implicit((Object)(object)_mainCamera) && (Object)(object)_mainCamera != (Object)(object)_camera)
			{
				return _mainCamera;
			}
			float unscaledTime = Time.unscaledTime;
			if (!force && unscaledTime < _nextCameraRetryAt)
			{
				if (!Object.op_Implicit((Object)(object)_mainCamera) || !((Object)(object)_mainCamera != (Object)(object)_camera))
				{
					return null;
				}
				return _mainCamera;
			}
			_nextCameraRetryAt = unscaledTime + 1f;
			_mainCamera = Camera.main;
			if ((Object)(object)_mainCamera == (Object)(object)_camera)
			{
				_mainCamera = null;
			}
			return _mainCamera;
		}

		private void OnBeginCameraRendering(ScriptableRenderContext _, Camera renderingCamera)
		{
			if ((Object)(object)renderingCamera != (Object)(object)_camera)
			{
				return;
			}
			if (ShouldTemporarilyRevealGhost())
			{
				for (int i = 0; i < _renderers.Length; i++)
				{
					Renderer val = _renderers[i];
					if (ShouldUseRenderer(val, allowDisabled: true) && !val.enabled)
					{
						_temporarilyEnabledRenderers[i] = true;
						val.enabled = true;
					}
				}
			}
			if (!ShouldTemporarilyRevealLocalCharacter())
			{
				return;
			}
			EnsureRendererPropertyBlockCache();
			for (int j = 0; j < _renderers.Length; j++)
			{
				Renderer val2 = _renderers[j];
				if (ShouldUseRenderer(val2, allowDisabled: false))
				{
					MaterialPropertyBlock val3 = _originalRendererBlocks[j];
					MaterialPropertyBlock val4 = _previewRendererBlocks[j];
					val3.Clear();
					val4.Clear();
					val2.GetPropertyBlock(val3);
					val2.GetPropertyBlock(val4);
					val4.SetFloat(VertexGhost, 0f);
					val2.SetPropertyBlock(val4);
					_temporarilyOverriddenRenderers[j] = true;
				}
			}
		}

		private void OnEndCameraRendering(ScriptableRenderContext _, Camera renderingCamera)
		{
			if ((Object)(object)renderingCamera == (Object)(object)_camera)
			{
				RestoreTemporarilyEnabledRenderers();
			}
		}

		private bool ShouldTemporarilyRevealGhost()
		{
			try
			{
				return _usingGhost && Object.op_Implicit((Object)(object)_character) && _character.IsLocal;
			}
			catch
			{
				return false;
			}
		}

		private bool ShouldTemporarilyRevealLocalCharacter()
		{
			try
			{
				int result;
				if (!_usingGhost && Object.op_Implicit((Object)(object)_character) && _character.IsLocal)
				{
					CharacterData data = _character.data;
					if (data == null || !data.dead)
					{
						CharacterData data2 = _character.data;
						result = ((data2 == null || !data2.fullyPassedOut) ? 1 : 0);
						goto IL_005b;
					}
				}
				result = 0;
				goto IL_005b;
				IL_005b:
				return (byte)result != 0;
			}
			catch
			{
				return false;
			}
		}

		private void EnsureRendererPropertyBlockCache()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			if (_originalRendererBlocks.Length != _renderers.Length || _previewRendererBlocks.Length != _renderers.Length)
			{
				_originalRendererBlocks = (MaterialPropertyBlock[])(object)new MaterialPropertyBlock[_renderers.Length];
				_previewRendererBlocks = (MaterialPropertyBlock[])(object)new MaterialPropertyBlock[_renderers.Length];
				for (int i = 0; i < _renderers.Length; i++)
				{
					_originalRendererBlocks[i] = new MaterialPropertyBlock();
					_previewRendererBlocks[i] = new MaterialPropertyBlock();
				}
			}
		}

		private void RestoreTemporarilyEnabledRenderers()
		{
			Renderer[] renderers = _renderers;
			int num = ((renderers != null) ? renderers.Length : 0);
			bool[] temporarilyEnabledRenderers = _temporarilyEnabledRenderers;
			int num2 = Mathf.Min(num, (temporarilyEnabledRenderers != null) ? temporarilyEnabledRenderers.Length : 0);
			for (int i = 0; i < num2; i++)
			{
				if (_temporarilyEnabledRenderers != null && !_temporarilyEnabledRenderers[i])
				{
					continue;
				}
				if (_renderers != null)
				{
					Renderer val = _renderers[i];
					if (Object.op_Implicit((Object)(object)val))
					{
						val.enabled = false;
					}
				}
				bool[] temporarilyEnabledRenderers2 = _temporarilyEnabledRenderers;
				if (temporarilyEnabledRenderers2 != null)
				{
					temporarilyEnabledRenderers2[i] = false;
				}
			}
			Renderer[] renderers2 = _renderers;
			int num3 = ((renderers2 != null) ? renderers2.Length : 0);
			bool[] temporarilyOverriddenRenderers = _temporarilyOverriddenRenderers;
			int num4 = Mathf.Min(num3, (temporarilyOverriddenRenderers != null) ? temporarilyOverriddenRenderers.Length : 0);
			int num5 = num4;
			MaterialPropertyBlock[] originalRendererBlocks = _originalRendererBlocks;
			num4 = Mathf.Min(num5, (originalRendererBlocks != null) ? originalRendererBlocks.Length : 0);
			for (int j = 0; j < num4; j++)
			{
				if (_temporarilyOverriddenRenderers != null && !_temporarilyOverriddenRenderers[j])
				{
					continue;
				}
				if (_renderers != null)
				{
					Renderer val2 = _renderers[j];
					if (Object.op_Implicit((Object)(object)val2) && _originalRendererBlocks != null)
					{
						val2.SetPropertyBlock(_originalRendererBlocks[j]);
					}
				}
				bool[] temporarilyOverriddenRenderers2 = _temporarilyOverriddenRenderers;
				if (temporarilyOverriddenRenderers2 != null)
				{
					temporarilyOverriddenRenderers2[j] = false;
				}
			}
		}

		private void ClearTarget()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)_target))
			{
				return;
			}
			RenderTexture active = RenderTexture.active;
			try
			{
				RenderTexture.active = _target;
				GL.Clear(true, true, BackgroundColor);
				_targetCleared = true;
			}
			finally
			{
				RenderTexture.active = active;
			}
		}

		private static Transform GetCharacterPreviewRoot(Character character)
		{
			if (!Object.op_Implicit((Object)(object)character))
			{
				return null;
			}
			CustomizationRefs val = (Object.op_Implicit((Object)(object)character.refs?.customization) ? character.refs.customization.refs : null);
			if (Object.op_Implicit((Object)(object)val))
			{
				return ((Component)val).transform;
			}
			if (!Object.op_Implicit((Object)(object)character.refs?.animationPositionTransform))
			{
				return ((Component)character).transform;
			}
			return character.refs.animationPositionTransform;
		}

		private static Player TryGetCharacterPlayer(Character character)
		{
			if (!Object.op_Implicit((Object)(object)character))
			{
				return null;
			}
			try
			{
				Player player = character.player;
				return Object.op_Implicit((Object)(object)player) ? player : null;
			}
			catch
			{
				return null;
			}
		}

		private static void TryGetRegisteredPlayerAndCharacter(int actorNumber, out Player player, out Character character)
		{
			player = null;
			character = null;
			try
			{
				player = PlayerHandler.GetPlayer(actorNumber);
				if (!Object.op_Implicit((Object)(object)player))
				{
					player = null;
				}
				else if (!PlayerHandler.TryGetCharacter(actorNumber, ref character) || !Object.op_Implicit((Object)(object)character))
				{
					character = null;
				}
			}
			catch
			{
				player = null;
				character = null;
			}
		}

		private static int ParseActorNumber(string actorText)
		{
			if (!int.TryParse(actorText, out var result) || result <= 0)
			{
				return -1;
			}
			return result;
		}

		private static bool IsFinite(Vector3 value)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			if (float.IsFinite(value.x) && float.IsFinite(value.y))
			{
				return float.IsFinite(value.z);
			}
			return false;
		}
	}
	internal static class CharacterEventNotifications
	{
		private const float Cooldown = 1.2f;

		private static readonly Dictionary<(int CharacterId, string Event), float> LastEvents = new Dictionary<(int, string), float>();

		private static readonly List<(int CharacterId, string Event)> ExpiredEvents = new List<(int, string)>();

		public static void OnRoomChanged()
		{
			LastEvents.Clear();
			ExpiredEvents.Clear();
		}

		public static void NotifyDied(Character character, RpcAttribution attribution)
		{
			if (Object.op_Implicit((Object)(object)character) && Object.op_Implicit((Object)(object)character.data) && character.data.dead)
			{
				NotifyCharacterEvent(character, "Player Died", NotificationKind.Error, "died", attribution, "killed", "died", localIsActor: false);
			}
		}

		public static void NotifyPassedOut(Character character, RpcAttribution attribution)
		{
			NotifyCharacterEvent(character, "Player Passed Out", NotificationKind.Warning, "passed-out", attribution, "knocked out", "passed out", localIsActor: false);
		}

		public static void NotifyRevived(Character character, RpcAttribution attribution)
		{
			NotifyCharacterEvent(character, "Player Revived", NotificationKind.Success, "revived", attribution, "revived", "revived", localIsActor: true);
		}

		private static void NotifyCharacterEvent(Character character, string title, NotificationKind kind, string key, RpcAttribution attribution, string remoteAction, string selfAction, bool localIsActor)
		{
			if (MenuFeatures.PlayerLifeNotifications && IsPlayerCharacter(character) && !IsCoolingDown((CharacterId: ((Object)character).GetInstanceID(), Event: key)))
			{
				NotificationSystem.Push(title, BuildLifeEventDescription(character, attribution, remoteAction, selfAction, localIsActor), kind);
			}
		}

		private static bool IsCoolingDown((int CharacterId, string Event) key)
		{
			float unscaledTime = Time.unscaledTime;
			if (LastEvents.TryGetValue(key, out var value) && unscaledTime - value < 1.2f)
			{
				return true;
			}
			if (LastEvents.Count >= 128)
			{
				foreach (KeyValuePair<(int, string), float> lastEvent in LastEvents)
				{
					if (unscaledTime - lastEvent.Value >= 1.2f)
					{
						ExpiredEvents.Add(lastEvent.Key);
					}
				}
				foreach (var expiredEvent in ExpiredEvents)
				{
					LastEvents.Remove(expiredEvent);
				}
				ExpiredEvents.Clear();
			}
			LastEvents[key] = unscaledTime;
			return false;
		}

		private static bool IsPlayerCharacter(Character character)
		{
			if (!Object.op_Implicit((Object)(object)character))
			{
				return false;
			}
			if (character.isBot || character.isZombie || character.isScoutmaster)
			{
				return false;
			}
			PhotonView photonView = GetPhotonView((Component)(object)character);
			if (Object.op_Implicit((Object)(object)photonView))
			{
				return photonView.Owner != null;
			}
			return false;
		}

		public static string GetCharacterNameForNotifications(Character character)
		{
			if (!Object.op_Implicit((Object)(object)character))
			{
				return "Unknown Player";
			}
			PhotonView photonView = GetPhotonView((Component)(object)character);
			if (!Object.op_Implicit((Object)(object)photonView) || photonView.Owner == null)
			{
				return "Player " + ((Object)character).GetInstanceID().ToString(CultureInfo.InvariantCulture);
			}
			string nickName = photonView.Owner.NickName;
			if (!string.IsNullOrWhiteSpace(nickName))
			{
				return nickName + " #" + photonView.Owner.ActorNumber.ToString(CultureInfo.InvariantCulture);
			}
			return "Player " + ((Object)character).GetInstanceID().ToString(CultureInfo.InvariantCulture);
		}

		private static string BuildLifeEventDescription(Character target, RpcAttribution attribution, string remoteAction, string selfAction, bool localIsActor)
		{
			string characterNameForNotifications = GetCharacterNameForNotifications(target);
			int characterActorNumber = GetCharacterActorNumber(target);
			if (TryGetAuthoritativeActor(attribution, out var sender, out var senderActor) && (senderActor != characterActorNumber || characterActorNumber <= 0))
			{
				return GetPlayerNameForNotifications(sender, senderActor, attribution?.SenderName) + " > " + remoteAction + " > " + characterNameForNotifications;
			}
			if (!localIsActor)
			{
				return characterNameForNotifications + " > " + selfAction;
			}
			Player localPlayer = PhotonNetwork.LocalPlayer;
			return GetPlayerNameForNotifications(localPlayer, (localPlayer != null) ? localPlayer.ActorNumber : 0, null) + " > " + selfAction + " > " + characterNameForNotifications;
		}

		private static bool TryGetAuthoritativeActor(RpcAttribution attribution, out Player sender, out int senderActor)
		{
			sender = null;
			senderActor = 0;
			if (attribution == null || !attribution.HasAuthoritativeSender)
			{
				return false;
			}
			senderActor = attribution.SenderActor;
			if (attribution.HasMessageInfo)
			{
				sender = attribution.MessageInfo.Sender;
			}
			if (sender == null)
			{
				sender = attribution.SenderPlayer;
			}
			if (sender != null || senderActor <= 0)
			{
				return senderActor > 0;
			}
			try
			{
				Room currentRoom = PhotonNetwork.CurrentRoom;
				sender = ((currentRoom != null) ? currentRoom.GetPlayer(senderActor, false) : null);
			}
			catch
			{
			}
			return senderActor > 0;
		}

		private static string GetPlayerNameForNotifications(Player sender, int senderActor, string fallbackName)
		{
			if (sender != null)
			{
				if (sender.IsLocal)
				{
					return "You";
				}
				return (string.IsNullOrWhiteSpace(sender.NickName) ? "Player" : sender.NickName.Trim()) + " #" + sender.ActorNumber.ToString(CultureInfo.InvariantCulture);
			}
			if (!string.IsNullOrWhiteSpace(fallbackName))
			{
				return fallbackName.Trim();
			}
			if (senderActor <= 0)
			{
				return "Unknown";
			}
			return "Player #" + senderActor.ToString(CultureInfo.InvariantCulture);
		}

		private static int GetCharacterActorNumber(Character character)
		{
			PhotonView photonView = GetPhotonView((Component)(object)character);
			Player obj = (Object.op_Implicit((Object)(object)photonView) ? (photonView.Owner ?? photonView.Controller) : null);
			if (obj == null)
			{
				return 0;
			}
			return obj.ActorNumber;
		}

		private static PhotonView GetPhotonView(Component component)
		{
			if (!Object.op_Implicit((Object)(object)component))
			{
				return null;
			}
			return component.GetComponent<PhotonView>() ?? component.GetComponentInChildren<PhotonView>();
		}
	}
	internal static class ConnectionLogText
	{
		private static Player _scopedPlayer;

		private static bool _scopedSessionTags;

		internal static MethodInfo AddMessageMethod => AccessTools.DeclaredMethod(typeof(PlayerConnectionLog), "AddMessage", new Type[1] { typeof(string) }, (Type[])null);

		internal static MethodInfo AddMessageDelayedMethod => AccessTools.DeclaredMethod(typeof(PlayerConnectionLog), "AddMessageDelayed", new Type[1] { typeof(string) }, (Type[])null);

		public static void BeginScope(Player player, bool includeSessionTags = true)
		{
			_scopedPlayer = player;
			_scopedSessionTags = includeSessionTags;
		}

		public static void EndScope()
		{
			_scopedPlayer = null;
			_scopedSessionTags = true;
		}

		public static string Decorate(string message)
		{
			if (_scopedPlayer == null || string.IsNullOrEmpty(message))
			{
				return message;
			}
			string text = ProfileNameColorRuntime.SanitizeRawNickname(_scopedPlayer.NickName);
			string text2 = ProfileNameColorRuntime.Format(_scopedPlayer);
			if (!string.IsNullOrEmpty(text) && !string.Equals(text, text2, StringComparison.Ordinal))
			{
				message = message.Replace(text, text2);
			}
			if (!MenuFeatures.GameTextTagNotifications)
			{
				return message;
			}
			return message + PlayerTagText.BuildRichSuffix(_scopedPlayer, _scopedSessionTags);
		}
	}
	public class GameEventNotifier : MonoBehaviourPunCallbacks
	{
		private static readonly string[] PlayerDirectoryPropertyKeys = new string[7] { "UserID", "ProductUserID", "PlatformFamily", "steamid", "steamId", "SteamId", "SteamID" };

		private readonly Dictionary<int, Coroutine> _pendingJoins = new Dictionary<int, Coroutine>();

		private float _nextBlacklistAudit;

		private void Update()
		{
			if (PhotonNetwork.InRoom && HostAuthority.IsLocalMaster() && !(Time.realtimeSinceStartup < _nextBlacklistAudit))
			{
				_nextBlacklistAudit = Time.realtimeSinceStartup + 3f;
				PlayerBlacklistStore.EnforceCurrentRoomBlacklist();
			}
		}

		public override void OnDisable()
		{
			((MonoBehaviourPunCallbacks)this).OnDisable();
			ResetRoomState();
		}

		public override void OnJoinedRoom()
		{
			PlayerBlacklistStore.ResetEnforcementState();
			_nextBlacklistAudit = 0f;
			CancelPendingLifecycleWork();
			PlayerOwnershipActions.ResetRoomState();
			PlayerDirectory.OnRoomChanged();
			CharacterEventNotifications.OnRoomChanged();
			PlayerFlagDetector.OnRoomChanged();
			NameSpoofProtectionRuntime.OnRoomChanged();
			ProfileNameColorRuntime.OnJoinedRoom();
			ChickenFeature.OnRoomJoined();
			IncomingRpcGuard.NoteRoomJoined();
			((MonoBehaviour)this).StartCoroutine(AuditExistingPlayersAfterJoin());
			Player localPlayer = PhotonNetwork.LocalPlayer;
			LateJoinAntiFlingRuntime.NoteJoin((localPlayer != null) ? localPlayer.ActorNumber : 0);
		}

		public override void OnLeftRoom()
		{
			ResetRoomState();
		}

		public override void OnDisconnected(DisconnectCause cause)
		{
			ResetRoomState();
		}

		private void ResetRoomState()
		{
			PlayerBlacklistStore.ResetEnforcementState();
			CancelPendingLifecycleWork();
			PlayerOwnershipActions.ResetRoomState();
			PlayerDirectory.OnRoomChanged();
			CharacterEventNotifications.OnRoomChanged();
			PlayerFlagDetector.OnRoomChanged();
			NameSpoofProtectionRuntime.OnRoomChanged();
			ProfileNameColorRuntime.OnLeftRoom();
			ChickenFeature.ResetRoomState();
			IncomingRpcGuard.NoteRoomLeft();
			LateJoinAntiFlingRuntime.NoteRoomLeft();
		}

		public override void OnPlayerEnteredRoom(Player newPlayer)
		{
			ChickenFeature.RefreshPublishedState(newPlayer);
			IncomingRpcGuard.NotePlayerJoined(newPlayer);
			LateJoinAntiFlingRuntime.NoteJoin((newPlayer != null) ? newPlayer.ActorNumber : 0);
			PlayerDirectory.RequestImmediateRefresh();
			if (newPlayer == null || newPlayer.IsLocal)
			{
				return;
			}
			int actorNumber = newPlayer.ActorNumber;
			PlayerBlacklistStore.TryBlock(newPlayer);
			if (actorNumber <= 0 || !_pendingJoins.ContainsKey(actorNumber))
			{
				Coroutine value = ((MonoBehaviour)this).StartCoroutine(ProcessPlayerJoined(newPlayer));
				if (actorNumber > 0)
				{
					_pendingJoins[actorNumber] = value;
				}
			}
		}

		public override void OnPlayerLeftRoom(Player otherPlayer)
		{
			IncomingRpcGuard.NotePlayerLeft(otherPlayer);
			LateJoinAntiFlingRuntime.NoteLeft((otherPlayer != null) ? otherPlayer.ActorNumber : 0);
			PlayerDirectory.RequestImmediateRefresh();
			if (otherPlayer != null && !otherPlayer.IsLocal)
			{
				int actorNumber = otherPlayer.ActorNumber;
				if (actorNumber > 0 && _pendingJoins.Remove(actorNumber, out var value) && value != null)
				{
					((MonoBehaviour)this).StopCoroutine(value);
				}
				((MonoBehaviour)this).StartCoroutine(ProcessPlayerLeft(otherPlayer));
			}
		}

		public override void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps)
		{
			if (targetPlayer != null && changedProps != null && ((Dictionary<object, object>)(object)changedProps).Count != 0)
			{
				if (((Dictionary<object, object>)(object)changedProps).ContainsKey((object)"CubeX.Chicken"))
				{
					ChickenFeature.RefreshPublishedState(targetPlayer);
				}
				bool num = ProfileNameColorRuntime.AffectsDisplayName(changedProps);
				bool flag = PlayerFlagDetector.ContainsKnownModFlagProperty(changedProps);
				if (num)
				{
					ProfileNameColorRuntime.OnPlayerPropertiesUpdate(targetPlayer, changedProps);
				}
				if (num || flag || ContainsDirectoryIdentityProperty(changedProps))
				{
					PlayerDirectory.RequestImmediateRefresh();
				}
				if (flag)
				{
					KnownCheaterProtectionRuntime.CheckKnownCheater(targetPlayer, "player properties update");
				}
				if (num || ContainsDirectoryIdentityProperty(changedProps))
				{
					PlayerBlacklistStore.TryBlock(targetPlayer);
					NameSpoofProtectionRuntime.CheckPlayer(targetPlayer, force: true);
				}
			}
		}

		public override void OnMasterClientSwitched(Player newMasterClient)
		{
			HostTakeoverProtectionPatch.OnMasterChanged(newMasterClient);
			PlayerDirectory.RequestImmediateRefresh();
			ProtectionLog.Write("INFO", "Host Authority", "Master client switched to " + GetPlayerName(newMasterClient) + ".");
			NotifyHostChanged(newMasterClient);
			if (newMasterClient != null && newMasterClient.IsLocal)
			{
				KnownCheaterProtectionRuntime.CheckAll("local master migration");
				NameSpoofProtectionRuntime.CheckAll(force: true);
				PlayerBlacklistStore.EnforceCurrentRoomBlacklist();
			}
		}

		private static void NotifyHostChanged(Player newMasterClient)
		{
			if (newMasterClient != null && MenuFeatures.HostChangeNotifications)
			{
				string description = (newMasterClient.IsLocal ? "You are now the host" : PlayerTagText.DescribeForMenu(newMasterClient, includeSessionTags: false));
				NotificationSystem.Push("Host Changed", description);
			}
		}

		private static string GetPlayerName(Player player)
		{
			if (player == null)
			{
				return "Unknown";
			}
			return (string.IsNullOrWhiteSpace(player.NickName) ? "Player" : player.NickName) + " #" + player.ActorNumber.ToString(CultureInfo.InvariantCulture);
		}

		private static bool ContainsDirectoryIdentityProperty(Hashtable changedProps)
		{
			string[] playerDirectoryPropertyKeys = PlayerDirectoryPropertyKeys;
			foreach (string key in playerDirectoryPropertyKeys)
			{
				if (((Dictionary<object, object>)(object)changedProps).ContainsKey((object)key))
				{
					return true;
				}
			}
			return false;
		}

		private IEnumerator ProcessPlayerJoined(Player player)
		{
			int actor = ((player != null) ? player.ActorNumber : 0);
			yield return null;
			RecentPlayersStore.Record(player);
			yield return null;
			if (!IsPlayerStillInRoom(player))
			{
				if (actor > 0)
				{
					_pendingJoins.Remove(actor);
				}
				yield break;
			}
			NameSpoofProtectionRuntime.CheckPlayer(player);
			bool flag = KnownCheaterProtectionRuntime.CheckKnownCheater(player, "room join");
			bool flag2 = PlayerBlacklistStore.TryBlock(player);
			bool handled = flag || flag2;
			yield return null;
			if (!handled && MenuFeatures.JoinLeaveNotifications && IsPlayerStillInRoom(player))
			{
				NotificationSystem.Push("Player Joined", PlayerTagText.DescribeForMenu(player), NotificationKind.Success);
			}
			if (actor > 0)
			{
				_pendingJoins.Remove(actor);
			}
		}

		private static IEnumerator AuditExistingPlayersAfterJoin()
		{
			yield return null;
			Player[] playerListOthers;
			try
			{
				playerListOthers = PhotonNetwork.PlayerListOthers;
			}
			catch
			{
				yield break;
			}
			if (playerListOthers == null)
			{
				yield break;
			}
			Player[] array = playerListOthers;
			foreach (Player player in array)
			{
				if (IsPlayerStillInRoom(player))
				{
					PlayerBlacklistStore.TryBlock(player);
					NameSpoofProtectionRuntime.CheckPlayer(player);
				}
				yield return null;
			}
		}

		private static IEnumerator ProcessPlayerLeft(Player player)
		{
			yield return null;
			RecentPlayersStore.Record(player);
			yield return null;
			if (MenuFeatures.JoinLeaveNotifications)
			{
				NotificationSystem.Push("Player Left", PlayerTagText.DescribeForMenu(player), NotificationKind.Warning);
			}
		}

		private static bool IsPlayerStillInRoom(Player player)
		{
			if (player == null || player.ActorNumber <= 0 || player.IsInactive || !PhotonNetwork.InRoom)
			{
				return false;
			}
			try
			{
				Room currentRoom = PhotonNetwork.CurrentRoom;
				return ((currentRoom != null) ? currentRoom.GetPlayer(player.ActorNumber, false) : null) == player;
			}
			catch
			{
				return false;
			}
		}

		private void CancelPendingLifecycleWork()
		{
			((MonoBehaviour)this).StopAllCoroutines();
			_pendingJoins.Clear();
		}
	}
	internal static class GameNotificationText
	{
		private static UI_Notifications _cached;

		public static bool Push(string message)
		{
			if (string.IsNullOrEmpty(message))
			{
				return false;
			}
			try
			{
				UI_Notifications val = Resolve();
				if (!Object.op_Implicit((Object)(object)val))
				{
					return false;
				}
				val.AddNotification(message);
				return true;
			}
			catch
			{
				return false;
			}
		}

		private static UI_Notifications Resolve()
		{
			if (Object.op_Implicit((Object)(object)_cached))
			{
				return _cached;
			}
			_cached = Object.FindAnyObjectByType<UI_Notifications>();
			return _cached;
		}
	}
	internal static class PlayerTagText
	{
		private static readonly Color YouColor = new Color(0.18f, 0.58f, 0.48f, 1f);

		private static readonly Color HostColor = new Color(0.18f, 0.36f, 0.88f, 1f);

		private static readonly Color FriendColor = new Color(0.22f, 0.5f, 0.9f, 1f);

		private static readonly Color BlacklistColor = new Color(0.82f, 0.18f, 0.16f, 1f);

		private static string GetGameName(Player player)
		{
			if (player == null)
			{
				return "Unknown";
			}
			if (!string.IsNullOrWhiteSpace(player.NickName))
			{
				return player.NickName.Trim();
			}
			return "Player";
		}

		private static string GetMenuName(Player player)
		{
			if (player == null)
			{
				return "Unknown";
			}
			return GetGameName(player) + " #" + player.ActorNumber.ToString(CultureInfo.InvariantCulture);
		}

		public static string DescribeForMenu(Player player, bool includeSessionTags = true)
		{
			return GetMenuName(player) + BuildPlainSuffix(player, includeSessionTags);
		}

		private static string BuildPlainSuffix(Player player, bool includeSessionTags = true)
		{
			IReadOnlyList<MenuTag> readOnlyList = BuildTags(player, includeSessionTags);
			if (readOnlyList.Count == 0)
			{
				return string.Empty;
			}
			StringBuilder stringBuilder = new StringBuilder();
			foreach (MenuTag item in readOnlyList)
			{
				stringBuilder.Append(" [").Append(item.Text).Append(']');
			}
			return stringBuilder.ToString();
		}

		public static string BuildRichSuffix(Player player, bool includeSessionTags = true)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			IReadOnlyList<MenuTag> readOnlyList = BuildTags(player, includeSessionTags);
			if (readOnlyList.Count == 0)
			{
				return string.Empty;
			}
			StringBuilder stringBuilder = new StringBuilder();
			foreach (MenuTag item in readOnlyList)
			{
				stringBuilder.Append(" <color=#").Append(ColorUtility.ToHtmlStringRGB(item.Color)).Append(">[")
					.Append(item.Text)
					.Append("]</color>");
			}
			return stringBuilder.ToString();
		}

		private static IReadOnlyList<MenuTag> BuildTags(Player player, bool includeSessionTags = true)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			List<MenuTag> list = new List<MenuTag>();
			if (player == null)
			{
				return list;
			}
			if (includeSessionTags && player.IsLocal)
			{
				Add(list, "YOU", YouColor);
			}
			if (includeSessionTags && IsHost(player))
			{
				Add(list, "HOST", HostColor);
			}
			ulong num = SafeGetSteamId(player);
			if (!player.IsLocal && num != 0L && SafeIsFriend(num))
			{
				Add(list, "FRIEND", FriendColor);
			}
			if (!player.IsLocal && SafeIsBlacklisted(player, num))
			{
				Add(list, "BLACKLIST", BlacklistColor);
			}
			foreach (MenuTag item in SafeBuildModFlagTags(player))
			{
				Add(list, item?.Text, item?.Color ?? BlacklistColor);
			}
			return list;
		}

		private static void Add(ICollection<MenuTag> tags, string tag, Color color)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			string text = tag?.Trim();
			if (string.IsNullOrEmpty(text))
			{
				return;
			}
			foreach (MenuTag tag2 in tags)
			{
				if (string.Equals(tag2.Text, text, StringComparison.OrdinalIgnoreCase))
				{
					return;
				}
			}
			tags.Add(new MenuTag(text.ToUpperInvariant(), color));
		}

		private static bool IsHost(Player player)
		{
			try
			{
				return player.IsMasterClient;
			}
			catch
			{
				return false;
			}
		}

		private static ulong SafeGetSteamId(Player player)
		{
			try
			{
				return RecentPlayersStore.TryGetSteamId(player);
			}
			catch
			{
				return 0uL;
			}
		}

		private static bool SafeIsFriend(ulong steamId)
		{
			try
			{
				return SteamPlayerActions.IsFriend(steamId);
			}
			catch
			{
				return false;
			}
		}

		private static bool SafeIsBlacklisted(Player player, ulong steamId)
		{
			try
			{
				string actorText = ((player.ActorNumber > 0) ? player.ActorNumber.ToString(CultureInfo.InvariantCulture) : string.Empty);
				return PlayerBlacklistStore.ContainsIdentity(steamId, player.UserId, player.NickName, actorText);
			}
			catch
			{
				return false;
			}
		}

		private static IReadOnlyList<MenuTag> SafeBuildModFlagTags(Player player)
		{
			try
			{
				return PlayerFlagDetector.BuildTags(PlayerFlagDetector.GetFlagText(player, includeDetectedModder: true));
			}
			catch
			{
				return new List<MenuTag>();
			}
		}
	}
	public static class RpcEventNotifications
	{
		private const float Cooldown = 0.7f;

		private static readonly Dictionary<string, float> LastEvents = new Dictionary<string, float>();

		public static void NotifyExecuted(string methodName, Player sender, PhotonView view)
		{
			if (MenuFeatures.RpcNotifications && !string.IsNullOrEmpty(methodName) && !IncomingRpcGuard.ShouldSuppressFallRpcNotification(methodName, sender, view) && !IsCoolingDown("rpc:" + methodName + ":" + GetSenderKey(sender) + ":" + (Object.op_Implicit((Object)(object)view) ? view.ViewID.ToString(CultureInfo.InvariantCulture) : "0")))
			{
				string text = ((sender != null && sender.IsLocal) ? "You" : GetPlayerName(sender));
				string targetText = GetTargetText(view);
				string description = (string.IsNullOrEmpty(targetText) ? text : (text + " -> " + targetText));
				NotificationSystem.Push("RPC " + methodName, description);
			}
		}

		public static void NotifyBlocked(string methodName, Player sender)
		{
			if (MenuFeatures.RpcNotifications && !string.IsNullOrEmpty(methodName) && !IsCoolingDown("blocked:" + methodName + ":" + GetSenderKey(sender)))
			{
				NotificationSystem.Push("RPC Blocked", methodName + " from " + GetPlayerName(sender), NotificationKind.Warning);
			}
		}

		public static void NotifyProtectionDetected(string eventName, Player sender, PhotonView view)
		{
			if (MenuFeatures.RpcNotifications && !string.IsNullOrEmpty(eventName) && !IsCoolingDown("protection:" + eventName + ":" + GetSenderKey(sender) + ":" + (Object.op_Implicit((Object)(object)view) ? view.ViewID.ToString(CultureInfo.InvariantCulture) : "0")))
			{
				string targetText = GetTargetText(view);
				string text = eventName + " from " + GetPlayerName(sender);
				if (!string.IsNullOrEmpty(targetText))
				{
					text = text + " -> " + targetText;
				}
				NotificationSystem.Push("Modder Detection", text, NotificationKind.Warning);
			}
		}

		public static void NotifyProtectionBlocked(string eventName, Player sender)
		{
			if (MenuFeatures.RpcNotifications && !string.IsNullOrEmpty(eventName) && !IsCoolingDown("protection-blocked:" + eventName + ":" + GetSenderKey(sender)))
			{
				NotificationSystem.Push("Protection Blocked", eventName + " from " + GetPlayerName(sender), NotificationKind.Warning);
			}
		}

		private static bool IsCoolingDown(string key)
		{
			float unscaledTime = Time.unscaledTime;
			if (LastEvents.TryGetValue(key, out var value) && unscaledTime - value < 0.7f)
			{
				return true;
			}
			LastEvents[key] = unscaledTime;
			return false;
		}

		private static string GetSenderKey(Player sender)
		{
			if (sender != null)
			{
				return sender.ActorNumber.ToString(CultureInfo.InvariantCulture);
			}
			return "unknown";
		}

		private static string GetPlayerName(Player player)
		{
			if (player == null)
			{
				return "Unknown";
			}
			return (string.IsNullOrWhiteSpace(player.NickName) ? "Player" : player.NickName) + " #" + player.ActorNumber.ToString(CultureInfo.InvariantCulture);
		}

		private static string GetTargetText(PhotonView view)
		{
			if (!Object.op_Implicit((Object)(object)view))
			{
				return string.Empty;
			}
			Character val = ((Component)view).GetComponent<Character>() ?? ((Component)view).GetComponentInParent<Character>() ?? ((Component)view).GetComponentInChildren<Character>();
			if (Object.op_Implicit((Object)(object)val))
			{
				return CharacterEventNotifications.GetCharacterNameForNotifications(val);
			}
			return "View " + view.ViewID.ToString(CultureInfo.InvariantCulture);
		}
	}
	public struct ColorPreset
	{
		public readonly string Name;

		public readonly Color Color;

		public ColorPreset(string name, Color color)
		{
			//IL_0008: 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)
			Name = name;
			Color = color;
		}
	}
	public static class MenuConfig
	{
		private const float ReferenceWidth = 1920f;

		private const float ReferenceHeight = 1080f;

		private const float MinUIScale = 0.5f;

		private const float MaxConfiguredUIScale = 4f;

		private const float DefaultMenuWidth = 480f;

		private const float DefaultUIScale = 1f;

		private const float DefaultHighlightLerpSpeed = 18f;

		private const int DefaultMaxVisibleRows = 12;

		public static readonly ColorPreset[] Presets = new ColorPreset[8]
		{
			new ColorPreset("Teal", new Color(0.243f, 0.706f, 0.537f, 1f)),
			new ColorPreset("Purple", new Color(0.486f, 0.361f, 1f, 1f)),
			new ColorPreset("Crimson", new Color(0.937f, 0.267f, 0.267f, 1f)),
			new ColorPreset("Sky", new Color(0.231f, 0.62f, 0.965f, 1f)),
			new ColorPreset("Lime", new Color(0.486f, 0.831f, 0.267f, 1f)),
			new ColorPreset("Amber", new Color(0.976f, 0.69f, 0.086f, 1f)),
			new ColorPreset("Pink", new Color(0.945f, 0.345f, 0.62f, 1f)),
			new ColorPreset("Cyan", new Color(0.063f, 0.808f, 0.851f, 1f))
		};

		public static int PresetIndex;

		public static Color AccentColor = Presets[0].Color;

		public static float MenuWidth = 480f;

		public static float UIScale = 1f;

		public static float HighlightLerpSpeed = 18f;

		public static int MaxVisibleRows = 12;

		public static bool ShowBreadcrumb = true;

		public static bool ShowDescription = true;

		public static bool ShowFooter = true;

		public static bool ShowScrollbar = true;

		public static bool AutoSave;

		public static bool AutoLoadOnStart = true;

		public static bool OpenMenuOnLaunch = true;

		public static bool UseClickGui;

		public static void ApplyPreset(int index)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			int num = Presets.Length;
			PresetIndex = (index % num + num) % num;
			AccentColor = Presets[PresetIndex].Color;
		}

		public static void SetAccentColor(Color color)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_0053: 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)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
			if (!NumericValue.IsFinite(color.r) || !NumericValue.IsFinite(color.g) || !NumericValue.IsFinite(color.b))
			{
				return;
			}
			AccentColor = new Color(Mathf.Clamp01(color.r), Mathf.Clamp01(color.g), Mathf.Clamp01(color.b), 1f);
			for (int i = 0; i < Presets.Length; i++)
			{
				Color color2 = Presets[i].Color;
				if (Mathf.Abs(color2.r - AccentColor.r) <= 0.001f && Mathf.Abs(color2.g - AccentColor.g) <= 0.001f && Mathf.Abs(color2.b - AccentColor.b) <= 0.001f)
				{
					PresetIndex = i;
					break;
				}
			}
		}

		public static float GetMaxUIScale()
		{
			if (Screen.width <= 0 || Screen.height <= 0)
			{
				return 4f;
			}
			float num = (float)Screen.width / 1920f;
			float num2 = (float)Screen.height / 1080f;
			return Mathf.Clamp(Mathf.Min(num, num2), 1f, 4f);
		}

		public static float GetResolvedUIScale()
		{
			return NumericValue.Clamp(UIScale, 0.5f, GetMaxUIScale(), 1f);
		}

		public static void SetUIScale(float scale)
		{
			UIScale = NumericValue.Clamp(scale, 0.5f, GetMaxUIScale(), 1f);
		}

		public static void ResetToDefaults()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			PresetIndex = 0;
			AccentColor = Presets[0].Color;
			MenuWidth = 480f;
			UIScale = 1f;
			HighlightLerpSpeed = 18f;
			MaxVisibleRows = 12;
			ShowBreadcrumb = true;
			ShowDescription = true;
			ShowFooter = true;
			ShowScrollbar = true;
			AutoSave = false;
			AutoLoadOnStart = true;
			OpenMenuOnLaunch = true;
			UseClickGui = false;
		}
	}
	internal static class ClickGuiIcons
	{
		private const int TexSize = 48;

		private static readonly Dictionary<string, Texture2D> Cache = new Dictionary<string, Texture2D>(StringComparer.OrdinalIgnoreCase);

		private static readonly Dictionary<string, string> CategoryShapes = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
		{
			["Self"] = "person",
			["Network"] = "people",
			["Players"] = "people",
			["Enemies"] = "people",
			["Items"] = "box",
			["Teleport"] = "pin",
			["Spawn"] = "plus",
			["ESP"] = "eye",
			["Visuals"] = "eye",
			["Performance"] = "gauge",
			["World"] = "globe",
			["Host"] = "crown",
			["Misc"] = "dots",
			["Search"] = "magnifier",
			["Settings"] = "gear"
		};

		public static Texture2D Tick => Get("tick");

		public static Texture2D Swap => Get("swap");

		public static void Shutdown()
		{
			foreach (Texture2D value in Cache.Values)
			{
				if ((Object)(object)value != (Object)null)
				{
					Object.Destroy((Object)(object)value);
				}
			}
			Cache.Clear();
		}

		public static Texture2D ForCategory(string category)
		{
			if (string.IsNullOrEmpty(category))
			{
				return null;
			}
			if (!CategoryShapes.TryGetValue(category, out var value))
			{
				return null;
			}
			return Get(value);
		}

		public static void Draw(Rect rect, Texture2D icon, Color tint)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)icon))
			{
				Color color = GUI.color;
				GUI.color = tint;
				GUI.DrawTexture(rect, (Texture)(object)icon, (ScaleMode)2, true);
				GUI.color = color;
			}
		}

		private static Texture2D Get(string shape)
		{
			if (Cache.TryGetValue(shape, out var value) && Object.op_Implicit((Object)(object)value))
			{
				return value;
			}
			Func<float, float, bool> shapeFunction = GetShapeFunction(shape);
			if (shapeFunction == null)
			{
				return null;
			}
			Texture2D val = Render(shapeFunction);
			Cache[shape] = val;
			return val;
		}

		private static Func<float, float, bool> GetShapeFunction(string shape)
		{
			return shape switch
			{
				"person" => (float x, float y) => Person(x, y, 0f, 0f, 1f), 
				"people" => People, 
				"box" => BoxIcon, 
				"pin" => Pin, 
				"plus" => Plus, 
				"eye" => Eye, 
				"gauge" => Gauge, 
				"globe" => Globe, 
				"crown" => Crown, 
				"dots" => Dots, 
				"magnifier" => Magnifier, 
				"gear" => Gear, 
				"swap" => SwapArrows, 
				"tick" => TickMark, 
				_ => null, 
			};
		}

		private static Texture2D Render(Func<float, float, bool> inside)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(48, 48, (TextureFormat)4, false)
			{
				hideFlags = (HideFlags)61,
				wrapMode = (TextureWrapMode)1,
				filterMode = (FilterMode)1
			};
			for (int i = 0; i < 48; i++)
			{
				for (int j = 0; j < 48; j++)
				{
					float num = 0f;
					for (int k = 0; k < 2; k++)
					{
						for (int l = 0; l < 2; l++)
						{
							float arg = ((float)j + 0.25f + (float)l * 0.5f) / 48f * 2f - 1f;
							float arg2 = ((float)i + 0.25f + (float)k * 0.5f) / 48f * 2f - 1f;
							if (inside(arg, arg2))
							{
								num += 0.25f;
							}
						}
					}
					val.SetPixel(j, i, new Color(1f, 1f, 1f, num));
				}
			}
			val.Apply(false, false);
			return val;
		}

		private static bool Person(float x, float y, float cx, float cy, float s)
		{
			x = (x - cx) / s;
			y = (y - cy) / s;
			if (Circle(x, y, 0f, 0.42f, 0.3f))
			{
				return true;
			}
			float num = x / 0.52f;
			float num2 = (y + 0.52f) / 0.52f;
			if (num * num + num2 * num2 <= 1f)
			{
				return y <= -0.16f;
			}
			return false;
		}

		private static bool People(float x, float y)
		{
			if (!Person(x, y, -0.3f, 0.1f, 0.78f))
			{
				return Person(x, y, 0.38f, -0.16f, 0.7f);
			}
			return true;
		}

		private static bool BoxIcon(float x, float y)
		{
			if (!RoundRect(x, y, 0f, -0.05f, 0.62f, 0.55f, 0.1f))
			{
				return false;
			}
			if (!(y > 0.28f))
			{
				return y < 0.16f;
			}
			return true;
		}

		private static bool Pin(float x, float y)
		{
			if (Circle(x, y, 0f, 0.3f, 0.5f) && !Circle(x, y, 0f, 0.3f, 0.2f))
			{
				return true;
			}
			return Tri(x, y, -0.33f, 0.05f, 0.33f, 0.05f, 0f, -0.85f);
		}

		private static bool Plus(float x, float y)
		{
			if (!RoundRect(x, y, 0f, 0f, 0.58f, 0.17f, 0.08f))
			{
				return RoundRect(x, y, 0f, 0f, 0.17f, 0.58f, 0.08f);
			}
			return true;
		}

		private static bool Eye(float x, float y)
		{
			if (!Circle(x, y, 0f, 0.62f, 1.05f) || !Circle(x, y, 0f, -0.62f, 1.05f))
			{
				return false;
			}
			if (Circle(x, y, 0f, 0f, 0.34f))
			{
				return Circle(x, y, 0f, 0f, 0.15f);
			}
			return true;
		}

		private static bool Gauge(float x, float y)
		{
			float num = Mathf.Sqrt(x * x + y * y);
			bool num2 = num >= 0.64f && num <= 0.82f && y >= -0.28f;
			bool flag = Segment(x, y, -0.64f, -0.3f, 0.64f, -0.3f, 0.09f);
			bool flag2 = Segment(x, y, -0.02f, -0.18f, 0.48f, 0.34f, 0.1f);
			if (!(num2 || flag || flag2))
			{
				return Circle(x, y, -0.02f, -0.18f, 0.15f);
			}
			return true;
		}

		private static bool Globe(float x, float y)
		{
			if (Ring(x, y, 0f, 0f, 0.82f, 0.64f))
			{
				return true;
			}
			if (!Circle(x, y, 0f, 0f, 0.72f))
			{
				return false;
			}
			if (Mathf.Abs(y) <= 0.09f)
			{
				return true;
			}
			float num = x / 0.36f;
			float num2 = y / 0.8f;
			return Mathf.Abs(Mathf.Sqrt(num * num + num2 * num2) - 1f) <= 0.16f;
		}

		private static bool Crown(float x, float y)
		{
			if (!RoundRect(x, y, 0f, -0.6f, 0.72f, 0.14f, 0.06f) && !Tri(x, y, -0.74f, -0.38f, -0.18f, -0.38f, -0.6f, 0.55f) && !Tri(x, y, -0.32f, -0.38f, 0.32f, -0.38f, 0f, 0.72f))
			{
				return Tri(x, y, 0.18f, -0.38f, 0.74f, -0.38f, 0.6f, 0.55f);
			}
			return true;
		}

		private static bool Dots(float x, float y)
		{
			if (!Circle(x, y, -0.58f, 0f, 0.18f) && !Circle(x, y, 0f, 0f, 0.18f))
			{
				return Circle(x, y, 0.58f, 0f, 0.18f);
			}
			return true;
		}

		private static bool Magnifier(float x, float y)
		{
			if (!Ring(x, y, -0.18f, 0.18f, 0.54f, 0.36f))
			{
				return Segment(x, y, 0.24f, -0.24f, 0.7f, -0.7f, 0.13f);
			}
			return true;
		}

		private static bool Gear(float x, float y)
		{
			float num = Mathf.Sqrt(x * x + y * y);
			if (num >= 0.3f && num <= 0.62f)
			{
				return true;
			}
			if (num > 0.62f && num <= 0.88f)
			{
				float num2 = Mathf.Repeat(Mathf.Atan2(y, x), MathF.PI / 4f);
				if (!(num2 <= 0.26f))
				{
					return num2 >= 0.5253982f;
				}
				return true;
			}
			return false;
		}

		private static bool SwapArrows(float x, float