Decompiled source of CubeX v3.3.7

plugins/CubeX.dll

Decompiled 4 days 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 BepInEx.Logging;
using CubeX.Core;
using CubeX.Features.Actions;
using CubeX.Features.Game;
using CubeX.Features.Host;
using CubeX.Features.Inventory;
using CubeX.Features.Misc;
using CubeX.Features.Misc.PauseMenuFeatures;
using CubeX.Features.Network;
using CubeX.Features.Performance;
using CubeX.Features.Player;
using CubeX.Features.Player.PlayerActions;
using CubeX.Features.Search;
using CubeX.Features.Self;
using CubeX.Features.Settings;
using CubeX.Features.Spawn;
using CubeX.Features.Teleport;
using CubeX.Features.Teleport.CampfireLocations;
using CubeX.Features.Visuals;
using CubeX.Features.Visuals.PlayerESP;
using CubeX.Features.World;
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 JetBrains.Annotations;
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 Steamworks;
using TMPro;
using Unity.Collections;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.Playables;
using UnityEngine.Rendering;
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.3.7.0")]
[assembly: AssemblyInformationalVersion("3.3.7+69bc80e61ab225469fb666fcec2a5612de54e480")]
[assembly: AssemblyProduct("Cube-X mod menu for PEAK")]
[assembly: AssemblyTitle("CubeX")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("3.3.7.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[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();
	}
}
[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();
	}
}
[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;
		}
	}
}
namespace CubeX
{
	[BepInPlugin("com.mister9982.cubex", "Cube-X", "3.3.7")]
	public class Plugin : BaseUnityPlugin
	{
		[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 Harmony _harmony;

		private readonly OwnedComponents _components = new OwnedComponents();

		private bool _initialized;

		private bool _shuttingDown;

		private int _lastTickFrame = -1;

		private bool _updateFailureLogged;

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

		private const string ModName = "Cube-X";

		public const string ModVersion = "3.3.7";

		public const string ModDisplayVersion = "3.3.7";

		public static Plugin Instance { get; private set; }

		public static ManualLogSource Log { get; private set; }

		private static FeatureManager FeatureManager { get; set; }

		private static MenuUI Menu { get; set; }

		internal static MenuUI MenuUi => Menu;

		private void Awake()
		{
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Expected O, but got Unknown
			//IL_00fa: 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;
			Log = ((BaseUnityPlugin)this).Logger;
			try
			{
				FeatureManager = new FeatureManager();
				FeatureManager.RegisterAllFromAssembly();
				ConfigService.Initialize(FeatureManager);
				Menu = _components.Track(((Component)this).gameObject.AddComponent<MenuUI>());
				Menu.Bind(FeatureManager, new SelectedPlayerPreviewPanel());
				_components.Track<GameEventNotifier>(((Component)this).gameObject.AddComponent<GameEventNotifier>());
				_components.Track(BeeDeaggroRuntime.Ensure());
				_components.Track(SteamLobbyJoinCoordinator.Ensure());
				NotificationSystem.MarkReady();
				_harmony = new Harmony("com.mister9982.cubex");
				PatchAllSafely();
				Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
				_initialized = true;
				CubeXDiagnostics.Info("Cube-X", string.Format("v{0} loaded - press {1} to open.", "3.3.7", RuntimeKeybinds.MenuBind), notify: true);
			}
			catch (Exception exception)
			{
				CubeXDiagnostics.Error("Cube-X", "Startup failed.", exception);
				Shutdown();
			}
		}

		private void Update()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			if (!_initialized)
			{
				return;
			}
			try
			{
				MenuInputCapture.Tick();
				if (!RuntimeKeybinds.BlocksGlobalHotkeys && !((Object)(object)Menu == (Object)null))
				{
					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 (!_initialized)
			{
				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 (!_initialized)
			{
				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;
			_initialized = false;
			((Behaviour)this).enabled = false;
			CubeXDiagnostics.Try("Cube-X", "Cancel pending lobby join", SteamLobbyJoinCoordinator.Shutdown, 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", "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.3.7";
	}
	internal static class CubeXBuildIdentity
	{
		public const bool IsDeveloperBuild = false;
	}
}
namespace CubeX.UI
{
	[HarmonyPatch(typeof(Character), "RPCA_Die")]
	internal static class CharacterDiedNotificationPatch
	{
		private static void Postfix(Character __instance)
		{
			CharacterEventNotifications.NotifyDied(__instance, RpcSenderContext.Current);
		}
	}
	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)
		{
			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 (NotificationSettings.PlayerLife && 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)
			{
				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)
			{
				Player localPlayer = PhotonNetwork.LocalPlayer;
				return GetPlayerNameForNotifications(localPlayer, (localPlayer != null) ? localPlayer.ActorNumber : 0, null) + " > " + selfAction + " > " + characterNameForNotifications;
			}
			return characterNameForNotifications + " > " + selfAction;
		}

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

		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>();
		}
	}
	[HarmonyPatch(typeof(Character), "RPCA_PassOut")]
	internal static class CharacterPassedOutNotificationPatch
	{
		private static void Postfix(Character __instance)
		{
			CharacterEventNotifications.NotifyPassedOut(__instance, RpcSenderContext.Current);
		}
	}
	[HarmonyPatch(typeof(Character), "ReviveCharacter")]
	internal static class CharacterRevivedNotificationPatch
	{
		private static void Postfix(Character __instance)
		{
			CharacterEventNotifications.NotifyRevived(__instance, RpcSenderContext.Current);
		}
	}
	[HarmonyPatch(typeof(Character), "RPCA_ReviveAtPosition")]
	internal static class CharacterRevivedAtPositionNotificationPatch
	{
		private static void Postfix(Character __instance)
		{
			CharacterEventNotifications.NotifyRevived(__instance, RpcSenderContext.Current);
		}
	}
	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 (!NotificationSettings.GameTextTags)
			{
				return message;
			}
			return message + PlayerTagText.BuildRichSuffix(_scopedPlayer, _scopedSessionTags);
		}
	}
	public class GameEventNotifier : MonoBehaviourPunCallbacks
	{
		private readonly Dictionary<int, Coroutine> _pendingJoins = new Dictionary<int, Coroutine>();

		private static readonly string[] PlayerDirectoryPropertyKeys = new string[7] { "UserID", "ProductUserID", "PlatformFamily", "steamid", "steamId", "SteamId", "SteamID" };

		public override void OnJoinedRoom()
		{
			CancelPendingLifecycleWork();
			PlayerDirectory.OnRoomChanged();
			CharacterEventNotifications.OnRoomChanged();
			PlayerFlagDetector.OnRoomChanged();
			NameSpoofProtectionRuntime.OnRoomChanged();
			ProfileNameColorRuntime.OnJoinedRoom();
			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();
		}

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

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

		public override void OnPlayerEnteredRoom(Player newPlayer)
		{
			IncomingRpcGuard.NotePlayerJoined(newPlayer);
			LateJoinAntiFlingRuntime.NoteJoin((newPlayer != null) ? newPlayer.ActorNumber : 0);
			PlayerDirectory.RequestImmediateRefresh();
			if (newPlayer == null || newPlayer.IsLocal)
			{
				return;
			}
			int actorNumber = newPlayer.ActorNumber;
			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)
			{
				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))
				{
					NameSpoofProtectionRuntime.CheckPlayer(targetPlayer, force: true);
				}
			}
		}

		public override void OnMasterClientSwitched(Player 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 && NotificationSettings.HostChange)
			{
				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 handled = KnownCheaterProtectionRuntime.CheckKnownCheater(player, "room join") || PlayerBlacklistStore.TryBlock(player);
			yield return null;
			if (!handled && NotificationSettings.JoinLeave && 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[] players;
			try
			{
				players = PhotonNetwork.PlayerListOthers;
			}
			catch
			{
				yield break;
			}
			if (players == null)
			{
				yield break;
			}
			foreach (Player player in players)
			{
				if (IsPlayerStillInRoom(player))
				{
					NameSpoofProtectionRuntime.CheckPlayer(player);
				}
				yield return null;
			}
		}

		private static IEnumerator ProcessPlayerLeft(Player player)
		{
			yield return null;
			RecentPlayersStore.Record(player);
			yield return null;
			if (NotificationSettings.JoinLeave)
			{
				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;
		}
	}
	public static class NotificationSettings
	{
		public static bool JoinLeave = true;

		public static bool HostChange = true;

		public static bool GameTextTags = true;

		public static bool PlayerLife = true;

		public static bool RpcEvents = true;

		public static bool KeybindToggles = true;
	}
	internal static class PlayerTagText
	{
		private const int MaxModFlagTags = 3;

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

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

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

		public 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();
			for (int i = 0; i < readOnlyList.Count; i++)
			{
				stringBuilder.Append(" [").Append(readOnlyList[i].Text).Append(']');
			}
			return stringBuilder.ToString();
		}

		public static string BuildRichSuffix(Player player, bool includeSessionTags = true)
		{
			//IL_0034: 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();
			for (int i = 0; i < readOnlyList.Count; i++)
			{
				MenuTag menuTag = readOnlyList[i];
				stringBuilder.Append(" <color=#").Append(ColorUtility.ToHtmlStringRGB(menuTag.Color)).Append(">[")
					.Append(menuTag.Text)
					.Append("]</color>");
			}
			return stringBuilder.ToString();
		}

		public 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 (NotificationSettings.RpcEvents && !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 (NotificationSettings.RpcEvents && !string.IsNullOrEmpty(methodName) && !IncomingRpcGuard.ShouldSuppressFallRpcNotification(methodName, sender, null) && !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 (NotificationSettings.RpcEvents && !string.IsNullOrEmpty(eventName) && !IncomingRpcGuard.ShouldSuppressFallRpcNotification(eventName, sender, view) && !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 (NotificationSettings.RpcEvents && !string.IsNullOrEmpty(eventName) && !IncomingRpcGuard.ShouldSuppressFallRpcNotification(eventName, sender, null) && !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);
		}
	}
	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;
			}
			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_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: 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)
			bounds = default(Bounds);
			if (!Object.op_Implicit((Object)(object)_previewRoot) || _renderers == null || _renderers.Length == 0)
			{
				return false;
			}
			bool allowDisabled = ShouldTemporarilyRevealGhost();
			bool flag = false;
			for (int i = 0; i < _renderers.Length; i++)
			{
				Renderer val = _renderers[i];
				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_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: 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_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: 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 = 0.75f;
			float num5 = Mathf.Max(0.45f, num * 0.53f);
			float num6 = Mathf.Max(0.45f, num2 / Mathf.Max(0.1f, num4) * 0.68f);
			_camera.orthographicSize = Mathf.Max(num5, num6);
			_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);
			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[i])
				{
					Renderer val = _renderers[i];
					if (Object.op_Implicit((Object)(object)val))
					{
						val.enabled = false;
					}
					_temporarilyEnabledRenderers[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[j])
				{
					Renderer val2 = _renderers[j];
					if (Object.op_Implicit((Object)(object)val2))
					{
						val2.SetPropertyBlock(_originalRendererBlocks[j]);
					}
					_temporarilyOverriddenRenderers[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 character.refs.animationPositionTransform;
			}
			return ((Component)character).transform;
		}

		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 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",
			["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 y)
		{
			bool num = Segment(x, y, -0.6f, 0.35f, 0.18f, 0.35f, 0.1f) || Tri(x, y, 0.12f, 0.62f, 0.12f, 0.08f, 0.66f, 0.35f);
			bool flag = Segment(x, y, -0.18f, -0.35f, 0.6f, -0.35f, 0.1f) || Tri(x, y, -0.12f, -0.08f, -0.12f, -0.62f, -0.66f, -0.35f);
			return num || flag;
		}

		private static bool TickMark(float x, float y)
		{
			if (!Segment(x, y, -0.62f, 0.05f, -0.16f, -0.44f, 0.15f))
			{
				return Segment(x, y, -0.16f, -0.44f, 0.62f, 0.42f, 0.15f);
			}
			return true;
		}

		private static bool Circle(float x, float y, float cx, float cy, float r)
		{
			float num = x - cx;
			float num2 = y - cy;
			return num * num + num2 * num2 <= r * r;
		}

		private static bool Ring(float x, float y, float cx, float cy, float outer, float inner)
		{
			float num = x - cx;
			float num2 = y - cy;
			float num3 = num * num + num2 * num2;
			if (num3 <= outer * outer)
			{
				return num3 >= inner * inner;
			}
			return false;
		}

		private static bool RoundRect(float x, float y, float cx, float cy, float halfW, float halfH, float r)
		{
			float num = Mathf.Abs(x - cx) - halfW + r;
			float num2 = Mathf.Abs(y - cy) - halfH + r;
			float num3 = Mathf.Max(num, 0f);
			float num4 = Mathf.Max(num2, 0f);
			return Mathf.Sqrt(num3 * num3 + num4 * num4) + Mathf.Min(Mathf.Max(num, num2), 0f) - r <= 0f;
		}

		private static bool Segment(float x, float y, float x1, float y1, float x2, float y2, float radius)
		{
			float num = x - x1;
			float num2 = y - y1;
			float num3 = x2 - x1;
			float num4 = y2 - y1;
			float num5 = num3 * num3 + num4 * num4;
			float num6 = ((num5 > 0f) ? Mathf.Clamp01((num * num3 + num2 * num4) / num5) : 0f);
			float num7 = num - num3 * num6;
			float num8 = num2 - num4 * num6;
			return num7 * num7 + num8 * num8 <= radius * radius;
		}

		private static bool Tri(float x, float y, float ax, float ay, float bx, float by, float cx, float cy)
		{
			float num = EdgeSign(x, y, ax, ay, bx, by);
			float num2 = EdgeSign(x, y, bx, by, cx, cy);
			float num3 = EdgeSign(x, y, cx, cy, ax, ay);
			bool flag = num < 0f || num2 < 0f || num3 < 0f;
			bool flag2 = num > 0f || num2 > 0f || num3 > 0f;
			return !(flag && flag2);
		}

		private static float EdgeSign(float px, float py, float ax, float ay, float bx, float by)
		{
			return (px - bx) * (ay - by) - (ax - bx) * (py - by);
		}
	}
	internal static class ClickGuiTheme
	{
		public static readonly Color WindowBg = Hex("#1D222Cff");

		public static readonly Color PanelBg = Hex("#2A303Dff");

		public static readonly Color SidebarBg = Hex("#12151Cff");

		public static readonly Color TitleBg = Hex("#050505ff");

		public static readonly Color TabIdle = Hex("#222834ff");

		public static readonly Color TabHover = Hex("#2E3648ff");

		public static readonly Color Text = Hex("#ECEFF4ff");

		public static readonly Color TextDim = Hex("#97A1B5ff");

		public static readonly Color IconIdle = Hex("#C7CEDBff");

		public static readonly Color CheckboxOff = Hex("#454D5Dff");

		public static readonly Color SliderTrack = Hex("#0A0C11ff");

		public static readonly Color ButtonBg = Hex("#414959ff");

		public static readonly Color ButtonHover = Hex("#4E586Cff");

		public static readonly Color CollapseBg = Hex("#0A0D13ff");

		public static readonly Color CollapseHover = Hex("#141926ff");

		public static readonly Color SubmenuBg = Hex("#1B202Bff");

		public static readonly Color PanelLine = Hex("#1B2130ff");

		public static readonly Color InputBg = Hex("#12161FCC");

		public static GUIStyle Title;

		public static GUIStyle PanelHeader;

		public static GUIStyle RowLabel;

		public static GUIStyle RowValue;

		public static GUIStyle ButtonText;

		public static GUIStyle CollapseText;

		public static GUIStyle TabGlyph;

		public static GUIStyle Tooltip;

		public static GUIStyle TextInput;

		public static GUIStyle Check;

		private static bool _init;

		private static float _appliedScale = -1f;

		private static bool _roundedSupported = true;

		public static Color Accent => MenuConfig.AccentColor;

		public static void Init()
		{
			//IL_000e: 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_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Expected O, but got Unknown
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: 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_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Expected O, but got Unknown
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Expected O, but got Unknown
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Expected O, but got Unknown
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Expected O, but got Unknown
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Expected O, but got Unknown
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Expected O, but got Unknown
			if (!_init)
			{
				_init = true;
				GUIStyle val = new GUIStyle();
				val.normal.textColor = Text;
				val.fontStyle = (FontStyle)1;
				val.alignment = (TextAnchor)4;
				Title = val;
				GUIStyle val2 = new GUIStyle();
				val2.normal.textColor = Accent;
				val2.fontStyle = (FontStyle)1;
				val2.alignment = (TextAnchor)3;
				PanelHeader = val2;
				GUIStyle val3 = new GUIStyle();
				val3.normal.textColor = Text;
				val3.alignment = (TextAnchor)3;
				val3.clipping = (TextClipping)1;
				RowLabel = val3;
				GUIStyle val4 = new GUIStyle();
				val4.normal.textColor = TextDim;
				val4.alignment = (TextAnchor)5;
				val4.clipping = (TextClipping)1;
				RowValue = val4;
				GUIStyle val5 = new GUIStyle();
				val5.normal.textColor = Text;
				val5.fontStyle = (FontStyle)1;
				val5.alignment = (TextAnchor)4;
				val5.clipping = (TextClipping)1;
				ButtonText = val5;
				GUIStyle val6 = new GUIStyle();
				val6.normal.textColor = Text;
				val6.fontStyle = (FontStyle)1;
				val6.alignment = (TextAnchor)3;
				val6.clipping = (TextClipping)1;
				CollapseText = val6;
				GUIStyle val7 = new GUIStyle();
				val7.normal.textColor = Text;
				val7.fontStyle = (FontStyle)1;
				val7.alignment = (TextAnchor)4;
				TabGlyph = val7;
				GUIStyle val8 = new GUIStyle();
				val8.normal.textColor = Text;
				val8.fontStyle = (FontStyle)1;
				val8.alignment = (TextAnchor)4;
				val8.clipping = (TextClipping)1;
				Tooltip = val8;
				GUIStyle val9 = new GUIStyle();
				val9.normal.textColor = Text;
				val9.focused.textColor = Text;
				val9.active.textColor = Text;
				val9.hover.textColor = Text;
				val9.alignment = (TextAnchor)3;
				val9.clipping = (TextClipping)1;
				TextInput = val9;
				GUIStyle val10 = new GUIStyle();
				val10.normal.textColor = Color.white;
				val10.fontStyle = (FontStyle)1;
				val10.alignment = (TextAnchor)4;
				Check = val10;
				ApplyScale(1f);
			}
		}

		public static void ApplyScale(float scale)
		{
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Expected O, but got Unknown
			if (_init)
			{
				scale = Mathf.Clamp(scale, 0.5f, 4f);
				if (!Mathf.Approximately(_appliedScale, scale))
				{
					_appliedScale = scale;
					Title.fontSize = Font(15f, scale);
					PanelHeader.fontSize = Font(14f, scale);
					RowLabel.fontSize = Font(12f, scale);
					RowValue.fontSize = Font(11f, scale);
					ButtonText.fontSize = Font(12f, scale);
					CollapseText.fontSize = Font(13f, scale);
					TabGlyph.fontSize = Font(17f, scale);
					Tooltip.fontSize = Font(11f, scale);
					TextInput.fontSize = Font(12f, scale);
					TextInput.padding = new RectOffset(Mathf.RoundToInt(6f * scale), Mathf.RoundToInt(6f * scale), 0, 0);
					Check.fontSize = Font(12f, scale);
				}
			}
		}

		public static void SyncAccent()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (_init)
			{
				PanelHeader.normal.textColor = Accent;
			}
		}

		private static int Font(float baseSize, float scale)
		{
			return Mathf.Max(1, Mathf.RoundToInt(baseSize * scale));
		}

		private static Color Hex(string h)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			Color result = default(Color);
			ColorUtility.TryParseHtmlString(h, ref result);
			return result;
		}

		public static void Fill(Rect r, Color c)
		{
			//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)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)