Decompiled source of SomeEmotesREPO v2.0.1

SomeEmotesREPO.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using SomeEmotesREPO.Rig;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ImGogole")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("2.0.1.0")]
[assembly: AssemblyInformationalVersion("2.0.1+f27c2ea8bec42b944548707e484fe3b00ecfaa65")]
[assembly: AssemblyProduct("SomeEmotesREPO")]
[assembly: AssemblyTitle("SomeEmotesREPO")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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;
		}
	}
}
[Serializable]
public class Preferences
{
	public const int CurrentVersion = 2;

	public List<string> farovites = new List<string>();

	public int version;
}
[Serializable]
public class LegacyPreferences
{
	public KeyCode panelKey = (KeyCode)0;
}
namespace SomeEmotesREPO
{
	[HarmonyPatch(typeof(PlayerAvatar))]
	internal class AddEmoteSystemPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("Start")]
		private static void Start_Postfix(PlayerAvatar __instance)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if (GameManager.Multiplayer())
			{
				EmoteNetwork.Listen();
				EmoteSystem emoteSystem = ((Component)__instance).GetComponent<EmoteSystem>();
				if (!Object.op_Implicit((Object)(object)emoteSystem))
				{
					emoteSystem = ((Component)__instance).gameObject.AddComponent<EmoteSystem>();
				}
				emoteSystem.SetPlayerAvatar(__instance);
				if (__instance.photonView.IsMine)
				{
					SomeEmotesREPO.Logger.LogInfo((object)$"EmoteSystem has been added to the player. Press [{SomeEmotesREPO.EmoteKeyCode}] to see the Emote Panel.");
				}
			}
			else
			{
				SomeEmotesREPO.Logger.LogInfo((object)"Not in a multiplayer game : ignored.");
			}
		}
	}
	[HarmonyPatch(typeof(GameDirector))]
	internal class AddPatchGameDirector
	{
		[HarmonyPrefix]
		[HarmonyPatch("DeathStart")]
		private static void DeathStart_Prefix()
		{
			EmoteSystem instance = EmoteSystem.Instance;
			if ((Object)(object)instance != (Object)null && instance.IsEmoting)
			{
				instance.StopEmote();
			}
		}
	}
	[HarmonyPatch(typeof(PlayerExpression))]
	internal class AddPatchPlayerExpression
	{
		[HarmonyPrefix]
		[HarmonyPatch("DoExpression")]
		private static bool DoExpression_Prefix()
		{
			return !BlockBecauseEmoteIsPlaying();
		}

		[HarmonyPrefix]
		[HarmonyPatch("ToggleExpression")]
		private static bool ToggleExpression_Prefix()
		{
			return !BlockBecauseEmoteIsPlaying();
		}

		private static bool BlockBecauseEmoteIsPlaying()
		{
			EmoteSystem instance = EmoteSystem.Instance;
			return (Object)(object)instance != (Object)null && instance.IsEmoting;
		}
	}
	public static class EmoteBundleLoader
	{
		private static AssetBundle? emoteBundle;

		public static bool Loaded => (Object)(object)emoteBundle != (Object)null;

		public static AssetBundle? Load(string path)
		{
			if ((Object)(object)emoteBundle != (Object)null)
			{
				return emoteBundle;
			}
			emoteBundle = AssetBundle.LoadFromFile(path);
			if ((Object)(object)emoteBundle == (Object)null)
			{
				SomeEmotesREPO.Logger.LogWarning((object)("No emote bundle at " + path + "."));
			}
			return emoteBundle;
		}

		public static void Unload()
		{
			if (!((Object)(object)emoteBundle == (Object)null))
			{
				emoteBundle.Unload(true);
				emoteBundle = null;
			}
		}

		public static T? LoadAsset<T>(string name) where T : Object
		{
			if ((Object)(object)emoteBundle == (Object)null)
			{
				return default(T);
			}
			string[] allAssetNames = emoteBundle.GetAllAssetNames();
			foreach (string text in allAssetNames)
			{
				if (text.EndsWith(name, StringComparison.OrdinalIgnoreCase))
				{
					return emoteBundle.LoadAsset<T>(text);
				}
			}
			return default(T);
		}

		public static List<string> GetAllAnimNames()
		{
			List<string> list = new List<string>();
			if ((Object)(object)emoteBundle == (Object)null)
			{
				return list;
			}
			string[] allAssetNames = emoteBundle.GetAllAssetNames();
			foreach (string text in allAssetNames)
			{
				if (text.EndsWith(".anim", StringComparison.OrdinalIgnoreCase))
				{
					list.Add(text);
				}
			}
			return list;
		}
	}
	public static class EmoteCatalog
	{
		private static readonly List<string> AllNames = new List<string>();

		private static readonly Dictionary<string, int> Indices = new Dictionary<string, int>(StringComparer.Ordinal);

		private static readonly List<AnimationClip> Clips = new List<AnimationClip>();

		public static bool Loaded { get; private set; }

		public static int Count => AllNames.Count;

		public static IList<string> Names => AllNames;

		public static string Signature { get; private set; } = string.Empty;

		public static void Load()
		{
			if (Loaded)
			{
				return;
			}
			List<string> allAnimNames = EmoteBundleLoader.GetAllAnimNames();
			if (allAnimNames == null || allAnimNames.Count == 0)
			{
				SomeEmotesREPO.Logger.LogError((object)"[Catalog] No emote clip found in the bundle.");
				return;
			}
			SortedDictionary<string, string> sortedDictionary = new SortedDictionary<string, string>(StringComparer.Ordinal);
			foreach (string item in allAnimNames)
			{
				string text = ExtractName(item);
				if (text.Length != 0)
				{
					sortedDictionary[text] = item;
				}
			}
			foreach (KeyValuePair<string, string> item2 in sortedDictionary)
			{
				AnimationClip val = EmoteBundleLoader.LoadAsset<AnimationClip>(item2.Value);
				if ((Object)(object)val == (Object)null)
				{
					SomeEmotesREPO.Logger.LogWarning((object)("[Catalog] '" + item2.Key + "' could not be loaded, skipped."));
					continue;
				}
				if (!((Motion)val).isHumanMotion)
				{
					SomeEmotesREPO.Logger.LogWarning((object)("[Catalog] '" + item2.Key + "' is not a humanoid clip, so it cannot drive the dancer. Set the FBX rig to Humanoid and rebuild the bundle."));
				}
				if (!((Motion)val).isLooping)
				{
					SomeEmotesREPO.Logger.LogWarning((object)("[Catalog] '" + item2.Key + "' is not set to loop, so it will play once and freeze. Tick Loop Time on the clip and rebuild the bundle."));
				}
				Indices[item2.Key] = AllNames.Count;
				AllNames.Add(item2.Key);
				Clips.Add(val);
			}
			Signature = ComputeSignature();
			Loaded = AllNames.Count > 0;
			SomeEmotesREPO.Logger.LogInfo((object)$"[Catalog] {AllNames.Count} emotes loaded, signature {Signature}.");
		}

		public static bool IsValid(int index)
		{
			return index >= 0 && index < AllNames.Count;
		}

		public static string NameAt(int index)
		{
			return IsValid(index) ? AllNames[index] : string.Empty;
		}

		public static AnimationClip? ClipAt(int index)
		{
			return IsValid(index) ? Clips[index] : null;
		}

		public static int IndexOf(string name)
		{
			int value;
			return Indices.TryGetValue(name, out value) ? value : (-1);
		}

		private static string ComputeSignature()
		{
			uint num = 2166136261u;
			foreach (string allName in AllNames)
			{
				string text = allName;
				foreach (char c in text)
				{
					num = (num ^ c) * 16777619;
				}
				num = (num ^ 0xA) * 16777619;
			}
			return AllNames.Count + ":" + num.ToString("x8");
		}

		public static string ExtractName(string path)
		{
			if (string.IsNullOrWhiteSpace(path))
			{
				return string.Empty;
			}
			string text = path.Trim();
			int num = text.LastIndexOf('/');
			if (num >= 0)
			{
				text = text.Substring(num + 1);
			}
			if (text.EndsWith(".anim", StringComparison.OrdinalIgnoreCase))
			{
				text = text.Substring(0, text.Length - ".anim".Length);
			}
			return text;
		}

		public static List<string> DisplayOrder(IList<string>? favourites)
		{
			List<string> list = new List<string>(AllNames.Count);
			if (favourites != null)
			{
				foreach (string favourite in favourites)
				{
					if (Indices.ContainsKey(favourite) && !list.Contains(favourite))
					{
						list.Add(favourite);
					}
				}
			}
			foreach (string allName in AllNames)
			{
				if (!list.Contains(allName))
				{
					list.Add(allName);
				}
			}
			return list;
		}
	}
	public class EmoteLoader : MonoBehaviour
	{
		private const string PreferencesFileName = "preferences.json";

		private static EmoteLoader? instance;

		private AssetBundle? assetBundle;

		private Preferences preferences = new Preferences();

		private string preferencesPath = string.Empty;

		public static EmoteLoader? Instance => instance;

		public static List<string> DisplayOrder()
		{
			return EmoteCatalog.DisplayOrder(instance?.preferences.farovites);
		}

		public static IList<string> Favourites()
		{
			return ((Object)(object)instance != (Object)null) ? ((IList<string>)instance.preferences.farovites) : ((IList<string>)new List<string>());
		}

		private void Awake()
		{
			instance = this;
		}

		private void Start()
		{
			string text = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? Paths.PluginPath;
			assetBundle = LoadBundle(text);
			preferencesPath = Path.Combine(text, "preferences.json");
			LoadPreferences();
		}

		private static AssetBundle? LoadBundle(string pluginFolder)
		{
			string[] array = new string[4]
			{
				Path.Combine(pluginFolder, "emotes.bundle"),
				Path.Combine(pluginFolder, "emotes"),
				Path.Combine(pluginFolder, "Emotes", "emotes.bundle"),
				Path.Combine(pluginFolder, "Emotes", "emotes")
			};
			string[] array2 = array;
			foreach (string text in array2)
			{
				if (File.Exists(text))
				{
					AssetBundle val = EmoteBundleLoader.Load(text);
					if ((Object)(object)val != (Object)null)
					{
						SomeEmotesREPO.Logger.LogInfo((object)("Emote bundle loaded from " + text + "."));
						return val;
					}
				}
			}
			SomeEmotesREPO.Logger.LogError((object)("No emote bundle found in " + pluginFolder + ". Looked for 'emotes' and 'emotes.bundle', at the top level and under Emotes/. No emote will be available."));
			return null;
		}

		public static Font? GetFont()
		{
			EmoteLoader? emoteLoader = instance;
			object result;
			if (emoteLoader == null)
			{
				result = null;
			}
			else
			{
				AssetBundle? obj = emoteLoader.assetBundle;
				result = ((obj != null) ? ((IEnumerable<Font>)obj.LoadAllAssets<Font>()).FirstOrDefault((Func<Font, bool>)((Font f) => ((Object)f).name.ToLower().Contains("teko-regular"))) : null);
			}
			return (Font?)result;
		}

		private void LoadPreferences()
		{
			string text;
			try
			{
				text = File.ReadAllText(preferencesPath);
			}
			catch (Exception)
			{
				SomeEmotesREPO.Logger.LogInfo((object)"No usable preferences file, creating one.");
				preferences = new Preferences();
				SavePreferences();
				return;
			}
			try
			{
				preferences = JsonUtility.FromJson<Preferences>(text) ?? new Preferences();
			}
			catch (Exception)
			{
				preferences = new Preferences();
			}
			Migrate(text);
		}

		private unsafe void Migrate(string json)
		{
			//IL_0065: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Invalid comparison between Unknown and I4
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			if (preferences.version >= 2)
			{
				return;
			}
			if (preferences.version == 1)
			{
				KeyCode val = (KeyCode)0;
				try
				{
					LegacyPreferences legacyPreferences = JsonUtility.FromJson<LegacyPreferences>(json);
					if (legacyPreferences != null)
					{
						val = legacyPreferences.panelKey;
					}
				}
				catch (Exception)
				{
				}
				string text = ((object)(*(KeyCode*)(&val))/*cast due to .constrained prefix*/).ToString();
				if ((int)val != 0 && (int)val != 101 && SomeEmotesREPO.EmoteKey.Value == "F" && Array.IndexOf(SomeEmotesREPO.BindableKeys, text) >= 0)
				{
					SomeEmotesREPO.EmoteKey.Value = text;
					SomeEmotesREPO.Logger.LogInfo((object)("Your [" + text + "] emote key moved out of preferences.json and into the config, under 'Emote wheel / Key'."));
				}
			}
			preferences.version = 2;
			SavePreferences();
		}

		public void SavePreferences()
		{
			try
			{
				File.WriteAllText(preferencesPath, JsonUtility.ToJson((object)preferences));
			}
			catch (IOException ex)
			{
				SomeEmotesREPO.Logger.LogWarning((object)("Could not save preferences.json: " + ex.Message));
			}
		}

		public void AddFavorites(List<string>? favorites)
		{
			if (favorites == null || favorites.Count == 0)
			{
				return;
			}
			List<string> list = new List<string>(preferences.farovites);
			bool flag = false;
			foreach (string favorite in favorites)
			{
				if (EmoteCatalog.IndexOf(favorite) >= 0)
				{
					if (list.Remove(favorite))
					{
						flag = true;
						continue;
					}
					list.Insert(0, favorite);
					flag = true;
				}
			}
			if (flag)
			{
				int count = Mathf.Min(8, list.Count);
				preferences.farovites = list.GetRange(0, count);
				SavePreferences();
			}
		}
	}
	public class EmoteNetwork : MonoBehaviour, IOnEventCallback
	{
		private struct Pending
		{
			public int ViewId;

			public int EmoteIndex;

			public float Yaw;

			public float Expiry;

			public bool Stop;
		}

		private const byte PlayEvent = 171;

		private const byte StopEvent = 172;

		private const byte RequestState = 173;

		private const float PendingLifetime = 5f;

		private static readonly SendOptions Reliable = SendOptions.SendReliable;

		private static readonly RaiseEventOptions ToOthers = new RaiseEventOptions
		{
			Receivers = (ReceiverGroup)0
		};

		private static readonly HashSet<string> Unknown = new HashSet<string>(StringComparer.Ordinal);

		private readonly List<Pending> _pending = new List<Pending>();

		private static bool listening;

		public static EmoteNetwork? Instance { get; private set; }

		private void Awake()
		{
			Instance = this;
		}

		public static void Listen()
		{
			if (listening || (Object)(object)Instance == (Object)null)
			{
				return;
			}
			try
			{
				PhotonNetwork.AddCallbackTarget((object)Instance);
				listening = true;
				SomeEmotesREPO.Logger.LogInfo((object)"[Net] Listening for emote events.");
			}
			catch (Exception ex)
			{
				SomeEmotesREPO.Logger.LogError((object)("[Net] Could not subscribe to Photon events: " + ex.Message));
			}
		}

		private void OnDestroy()
		{
			if (listening)
			{
				PhotonNetwork.RemoveCallbackTarget((object)this);
				listening = false;
			}
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}

		public static void SendPlay(PhotonView view, string emote, float yaw)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			if (Connected(view) && !string.IsNullOrEmpty(emote))
			{
				PhotonNetwork.RaiseEvent((byte)171, (object)new object[3] { view.ViewID, emote, yaw }, ToOthers, Reliable);
			}
		}

		public static void SendStop(PhotonView view)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if (Connected(view))
			{
				PhotonNetwork.RaiseEvent((byte)172, (object)new object[1] { view.ViewID }, ToOthers, Reliable);
			}
		}

		public static void SendStateRequest()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			if (PhotonNetwork.InRoom)
			{
				PhotonNetwork.RaiseEvent((byte)173, (object)null, ToOthers, Reliable);
			}
		}

		private static bool Connected(PhotonView view)
		{
			return (Object)(object)view != (Object)null && PhotonNetwork.InRoom;
		}

		public void OnEvent(EventData photonEvent)
		{
			switch (photonEvent.Code)
			{
			case 171:
			{
				if (Unpack(photonEvent, 3, out object[] content2))
				{
					Apply((int)content2[0], (content2[1] as string) ?? string.Empty, (float)content2[2], stop: false);
				}
				break;
			}
			case 172:
			{
				if (Unpack(photonEvent, 1, out object[] content))
				{
					Apply((int)content[0], string.Empty, 0f, stop: true);
				}
				break;
			}
			case 173:
				Answer(photonEvent.Sender);
				break;
			}
		}

		private static bool Unpack(EventData photonEvent, int length, out object[] content)
		{
			content = (photonEvent.CustomData as object[]) ?? Array.Empty<object>();
			if (content.Length >= length)
			{
				return true;
			}
			SomeEmotesREPO.Logger.LogWarning((object)$"[Net] Ignored a malformed emote event ({photonEvent.Code}).");
			return false;
		}

		private void Apply(int viewId, string emote, float yaw, bool stop)
		{
			int num = 0;
			if (!stop)
			{
				num = EmoteCatalog.IndexOf(emote);
				if (num < 0)
				{
					if (Unknown.Add(emote))
					{
						SomeEmotesREPO.Logger.LogWarning((object)("[Net] A player danced '" + emote + "', which is not in this install " + $"({EmoteCatalog.Count} emotes, signature {EmoteCatalog.Signature}). " + "Their emote set differs from yours, so that one is skipped here."));
					}
					return;
				}
			}
			EmoteSystem emoteSystem = Resolve(viewId);
			if ((Object)(object)emoteSystem != (Object)null)
			{
				if (stop)
				{
					emoteSystem.ApplyStop();
				}
				else
				{
					emoteSystem.ApplyPlay(num, yaw);
				}
				return;
			}
			_pending.Add(new Pending
			{
				ViewId = viewId,
				EmoteIndex = num,
				Yaw = yaw,
				Stop = stop,
				Expiry = Time.time + 5f
			});
		}

		private void Answer(int actorNumber)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			EmoteSystem instance = EmoteSystem.Instance;
			if ((Object)(object)instance == (Object)null || !instance.IsEmoting)
			{
				return;
			}
			Player val = null;
			Player[] playerListOthers = PhotonNetwork.PlayerListOthers;
			foreach (Player val2 in playerListOthers)
			{
				if (val2.ActorNumber == actorNumber)
				{
					val = val2;
				}
			}
			if (val != null)
			{
				RaiseEventOptions val3 = new RaiseEventOptions();
				val3.TargetActors = new int[1] { actorNumber };
				RaiseEventOptions val4 = val3;
				PhotonNetwork.RaiseEvent((byte)171, (object)new object[3] { instance.ViewId, instance.CurrentEmoteName, instance.FrozenYaw }, val4, Reliable);
			}
		}

		private static EmoteSystem? Resolve(int viewId)
		{
			PhotonView val = PhotonView.Find(viewId);
			return ((Object)(object)val == (Object)null) ? null : ((Component)val).GetComponent<EmoteSystem>();
		}

		private void Update()
		{
			if (_pending.Count == 0)
			{
				return;
			}
			for (int num = _pending.Count - 1; num >= 0; num--)
			{
				Pending pending = _pending[num];
				EmoteSystem emoteSystem = Resolve(pending.ViewId);
				if ((Object)(object)emoteSystem != (Object)null)
				{
					if (pending.Stop)
					{
						emoteSystem.ApplyStop();
					}
					else
					{
						emoteSystem.ApplyPlay(pending.EmoteIndex, pending.Yaw);
					}
					_pending.RemoveAt(num);
				}
				else if (Time.time >= pending.Expiry)
				{
					_pending.RemoveAt(num);
				}
			}
		}
	}
	public class EmoteSystem : MonoBehaviourPun
	{
		private const float BindDelay = 0.75f;

		private const float CameraDistanceMin = 0.5f;

		private const float CameraDistanceMax = 4f;

		private static EmoteSystem? instance;

		private static float camOffset = 3.25f;

		private readonly EmoteRigPlayer _player = new EmoteRigPlayer();

		private PlayerAvatar playerAvatar = null;

		private PlayerAvatarVisuals? playerVisuals;

		private Transform? camTransform;

		private bool ready;

		private bool isEmoting;

		private int currentEmote = -1;

		private float frozenYaw;

		private bool controlArmed;

		internal bool flashlightHeld;

		public static EmoteSystem? Instance => instance;

		public static bool Ready => (Object)(object)instance != (Object)null && instance.ready;

		public bool IsEmoting => isEmoting;

		public int CurrentEmote => currentEmote;

		public string CurrentEmoteName => EmoteCatalog.NameAt(currentEmote);

		public float FrozenYaw => frozenYaw;

		public int ViewId => ((Object)(object)((MonoBehaviourPun)this).photonView != (Object)null) ? ((MonoBehaviourPun)this).photonView.ViewID : 0;

		public bool IsDead => (Object)(object)playerAvatar == (Object)null || playerAvatar.deadSet;

		private bool IsMine => (Object)(object)((MonoBehaviourPun)this).photonView != (Object)null && ((MonoBehaviourPun)this).photonView.IsMine;

		private void Awake()
		{
			ready = false;
			if ((Object)(object)Camera.main != (Object)null)
			{
				camTransform = ((Component)Camera.main).transform;
			}
		}

		public void SetPlayerAvatar(PlayerAvatar avatar)
		{
			playerAvatar = avatar;
			((MonoBehaviour)this).StartCoroutine(Bind());
		}

		private IEnumerator Bind()
		{
			yield return (object)new WaitForSeconds(0.75f);
			if ((Object)(object)playerAvatar == (Object)null)
			{
				yield break;
			}
			playerVisuals = EmoteRigPlayer.VisualsOf(playerAvatar);
			if ((Object)(object)playerVisuals == (Object)null)
			{
				SomeEmotesREPO.Logger.LogWarning((object)"[Emote] No PlayerAvatarVisuals on this avatar; emotes are disabled for it.");
				yield break;
			}
			EmoteCatalog.Load();
			if (!EmoteCatalog.Loaded)
			{
				SomeEmotesREPO.Logger.LogError((object)"[Emote] No emote loaded; the system stays off.");
				yield break;
			}
			if (IsMine)
			{
				instance = this;
				EmoteNetwork.SendStateRequest();
			}
			ready = true;
		}

		public void SetFavorite(string favorite)
		{
			SetFavorites(new List<string> { favorite });
		}

		public void SetFavorites(List<string> favorites)
		{
			EmoteLoader.Instance?.AddFavorites(favorites);
		}

		public void PlayEmote(string emoteName)
		{
			int num = EmoteCatalog.IndexOf(emoteName);
			if (num < 0)
			{
				SomeEmotesREPO.Logger.LogWarning((object)("[Emote] Unknown emote '" + emoteName + "'."));
			}
			else
			{
				PlayEmote(num);
			}
		}

		public void PlayEmote(int emoteIndex)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			if (ready && IsMine && EmoteCatalog.IsValid(emoteIndex))
			{
				EmoteWheel.Instance?.Close();
				float y = ((Component)playerAvatar).transform.eulerAngles.y;
				ApplyPlay(emoteIndex, y);
				EmoteNetwork.SendPlay(((MonoBehaviourPun)this).photonView, EmoteCatalog.NameAt(emoteIndex), y);
			}
		}

		public void StopEmote()
		{
			if (IsMine && isEmoting)
			{
				EmoteWheel.Instance?.Close();
				ApplyStop();
				EmoteNetwork.SendStop(((MonoBehaviourPun)this).photonView);
			}
		}

		internal void ApplyPlay(int emoteIndex, float yaw)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			if (ready && !((Object)(object)playerAvatar == (Object)null))
			{
				AnimationClip val = EmoteCatalog.ClipAt(emoteIndex);
				if (!((Object)(object)val == (Object)null) && _player.Play(playerAvatar, val, Quaternion.Euler(0f, yaw, 0f)))
				{
					currentEmote = emoteIndex;
					frozenYaw = yaw;
					isEmoting = true;
					controlArmed = false;
					SomeEmotesREPO.Logger.LogInfo((object)("[Emote] " + OwnerName() + " plays '" + EmoteCatalog.NameAt(emoteIndex) + "'."));
				}
			}
		}

		internal void ApplyStop()
		{
			isEmoting = false;
			currentEmote = -1;
			_player.Stop();
		}

		private void Update()
		{
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			if (!ready || !IsMine)
			{
				return;
			}
			if (isEmoting)
			{
				bool flag = (Object)(object)InputManager.instance != (Object)null && InputManager.instance.disableMovementTimer > 0f;
				if (!controlArmed)
				{
					controlArmed = !flag && !TookControlBack();
				}
				else if (TookControlBack())
				{
					StopEmote();
				}
			}
			if (!((Object)(object)camTransform != (Object)null))
			{
				return;
			}
			camTransform.localPosition = new Vector3(0f, 0f, (0f - camOffset) * _player.Weight);
			bool flag2 = (Object)(object)EmoteWheel.Instance != (Object)null && EmoteWheel.Instance.Visible;
			if (_player.Active && !flag2)
			{
				float y = Input.mouseScrollDelta.y;
				if (y != 0f)
				{
					camOffset = Mathf.Clamp(camOffset - y * Time.deltaTime * 20f, 0.5f, 4f);
				}
			}
		}

		private void LateUpdate()
		{
			if (_player.Active)
			{
				if (IsMine && (Object)(object)playerVisuals != (Object)null)
				{
					playerVisuals.ShowSelfOverride(0.1f);
				}
				_player.Tick(Time.deltaTime);
			}
			if (isEmoting && !_player.Playing)
			{
				isEmoting = false;
				currentEmote = -1;
				if (IsMine && (Object)(object)((MonoBehaviourPun)this).photonView != (Object)null)
				{
					EmoteNetwork.SendStop(((MonoBehaviourPun)this).photonView);
				}
			}
		}

		private bool TookControlBack()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)InputManager.instance == (Object)null)
			{
				return false;
			}
			Vector2 movement = InputManager.instance.GetMovement();
			if (((Vector2)(ref movement)).sqrMagnitude > 0.01f)
			{
				return true;
			}
			return InputManager.instance.KeyDown((InputKey)1) || InputManager.instance.KeyDown((InputKey)2) || InputManager.instance.KeyDown((InputKey)15) || InputManager.instance.KeyDown((InputKey)12) || InputManager.instance.KeyDown((InputKey)14);
		}

		private string OwnerName()
		{
			return ((Object)(object)((MonoBehaviourPun)this).photonView != (Object)null && ((MonoBehaviourPun)this).photonView.Owner != null) ? ((MonoBehaviourPun)this).photonView.Owner.NickName : ((Object)this).name;
		}

		private void OnDestroy()
		{
			_player.Dispose();
			if ((Object)(object)instance == (Object)(object)this)
			{
				instance = null;
			}
		}
	}
	public class EmoteWheel : MonoBehaviour
	{
		public const int Slots = 8;

		private const float DeadZone = 0.3f;

		private const float RadiusFraction = 0.26f;

		private const float CardWidthFraction = 0.155f;

		private const float CardHeightFraction = 0.052f;

		private static readonly Color Dim = new Color(0f, 0f, 0f, 0.45f);

		private static readonly Color CardFill = new Color(0.07f, 0.08f, 0.09f, 0.92f);

		private static readonly Color CardEdge = new Color(1f, 1f, 1f, 0.13f);

		private static readonly Color PickedFill = new Color(0.18f, 0.62f, 0.42f, 0.96f);

		private static readonly Color PickedEdge = new Color(0.55f, 0.95f, 0.75f, 0.9f);

		private static readonly Color Favourite = new Color(0.93f, 0.72f, 0.25f, 1f);

		private static readonly Color Faded = new Color(0.72f, 0.75f, 0.78f, 1f);

		private static EmoteWheel? instance;

		private readonly List<string> _page = new List<string>(8);

		private bool _open;

		private Vector2 _aim;

		private int _pageIndex;

		private int _picked = -1;

		private bool _wasHeld;

		private Texture2D? _white;

		private GUIStyle? _cardStyle;

		private GUIStyle? _titleStyle;

		private GUIStyle? _hintStyle;

		public static EmoteWheel? Instance => instance;

		public bool Visible => _open;

		private void Awake()
		{
			instance = this;
			SomeEmotesREPO.Logger.LogInfo((object)"Emote wheel ready.");
		}

		private void OnDestroy()
		{
			if ((Object)(object)instance == (Object)(object)this)
			{
				instance = null;
			}
			if ((Object)(object)_white != (Object)null)
			{
				Object.Destroy((Object)(object)_white);
			}
		}

		public void Close()
		{
			_open = false;
			_picked = -1;
		}

		private void Update()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			EmoteSystem emoteSystem = EmoteSystem.Instance;
			if ((Object)(object)emoteSystem == (Object)null || !EmoteCatalog.Loaded)
			{
				Close();
				_wasHeld = false;
				return;
			}
			bool flag = CanOpen(emoteSystem);
			bool flag2 = flag && Input.GetKey(SomeEmotesREPO.EmoteKeyCode);
			if (flag2 && !_wasHeld)
			{
				Open();
			}
			else if (!flag2 && _wasHeld)
			{
				if (flag)
				{
					Release(emoteSystem);
				}
				else
				{
					Close();
				}
			}
			_wasHeld = flag2;
			if (_open)
			{
				if ((Object)(object)InputManager.instance != (Object)null)
				{
					InputManager.instance.disableAimingTimer = 0.1f;
					InputManager.instance.DisableMovement(0.1f);
				}
				Paging();
				Aim();
				if (_picked >= 0 && Input.GetMouseButtonDown(1))
				{
					emoteSystem.SetFavorite(_page[_picked]);
					Rebuild();
				}
			}
		}

		private static bool CanOpen(EmoteSystem emotes)
		{
			if (emotes.IsDead)
			{
				return false;
			}
			return SemiFunc.NoTextInputsActive();
		}

		private void Open()
		{
			//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)
			_open = true;
			_aim = Vector2.zero;
			_picked = -1;
			_pageIndex = Mathf.Clamp(_pageIndex, 0, PageCount() - 1);
			Rebuild();
		}

		private void Release(EmoteSystem emotes)
		{
			bool flag = _open && _picked >= 0 && _picked < _page.Count;
			string emoteName = (flag ? _page[_picked] : string.Empty);
			Close();
			if (flag)
			{
				emotes.PlayEmote(emoteName);
			}
		}

		private void Aim()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = ((Mouse.current != null) ? ((InputControl<Vector2>)(object)((Pointer)Mouse.current).delta).ReadValue() : Vector2.zero);
			_aim = Vector2.ClampMagnitude(_aim + val * SomeEmotesREPO.WheelSensitivity.Value, 1f);
			if (((Vector2)(ref _aim)).magnitude < 0.3f)
			{
				_picked = -1;
				return;
			}
			float num = Mathf.Atan2(_aim.x, _aim.y) * 57.29578f;
			int num2 = Mathf.RoundToInt(num / 45f);
			num2 = (num2 % 8 + 8) % 8;
			_picked = ((num2 < _page.Count) ? num2 : (-1));
		}

		private void Paging()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			float y = Input.mouseScrollDelta.y;
			if (y != 0f)
			{
				int num = PageCount();
				if (num > 1)
				{
					int num2 = ((!(y > 0f)) ? 1 : (-1));
					_pageIndex = (_pageIndex + num2 + num) % num;
					Rebuild();
				}
			}
		}

		private static int PageCount()
		{
			return Mathf.Max(1, Mathf.CeilToInt((float)EmoteCatalog.Count / 8f));
		}

		private void Rebuild()
		{
			_page.Clear();
			_picked = -1;
			List<string> list = EmoteLoader.DisplayOrder();
			int num = _pageIndex * 8;
			for (int i = num; i < list.Count; i++)
			{
				if (_page.Count >= 8)
				{
					break;
				}
				_page.Add(list[i]);
			}
		}

		private void OnGUI()
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: 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_00cb: 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_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: 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_016d: Unknown result type (might be due to invalid IL or missing references)
			if (_open && _page.Count != 0)
			{
				EnsureStyles();
				float num = Screen.height;
				Vector2 val = default(Vector2);
				((Vector2)(ref val))..ctor((float)Screen.width * 0.5f, num * 0.5f);
				float num2 = num * 0.26f;
				float num3 = (float)Screen.width * 0.155f;
				float num4 = num * 0.052f;
				GUI.color = Dim;
				GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, num), (Texture)(object)_white);
				GUI.color = Color.white;
				HashSet<string> hashSet = new HashSet<string>(EmoteLoader.Favourites());
				Vector2 val2 = default(Vector2);
				Rect card = default(Rect);
				for (int i = 0; i < _page.Count; i++)
				{
					float num5 = (float)i * 45f * (MathF.PI / 180f);
					((Vector2)(ref val2))..ctor(val.x + Mathf.Sin(num5) * num2, val.y - Mathf.Cos(num5) * num2);
					((Rect)(ref card))..ctor(val2.x - num3 * 0.5f, val2.y - num4 * 0.5f, num3, num4);
					DrawCard(card, _page[i], i == _picked, hashSet.Contains(_page[i]));
				}
				DrawCentre(val, num2);
			}
		}

		private void DrawCard(Rect card, string emote, bool picked, bool favourite)
		{
			//IL_0006: 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)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: 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_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			if (picked)
			{
				card = Grow(card, ((Rect)(ref card)).height * 0.14f);
			}
			GUI.color = (picked ? PickedFill : CardFill);
			GUI.DrawTexture(card, (Texture)(object)_white);
			GUI.color = (picked ? PickedEdge : CardEdge);
			DrawEdge(card, picked ? 2f : 1f);
			if (favourite)
			{
				GUI.color = Favourite;
				GUI.DrawTexture(new Rect(((Rect)(ref card)).x, ((Rect)(ref card)).y, 3f, ((Rect)(ref card)).height), (Texture)(object)_white);
			}
			GUI.color = Color.white;
			_cardStyle.normal.textColor = (picked ? Color.white : Faded);
			GUI.Label(card, Pretty(emote), _cardStyle);
		}

		private void DrawCentre(Vector2 centre, float radius)
		{
			//IL_000b: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: 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_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			float num = radius * 1.15f;
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(centre.x - num * 0.5f, centre.y - 26f, num, 34f);
			bool flag = _picked >= 0 && _picked < _page.Count;
			GUI.color = Color.white;
			_titleStyle.normal.textColor = (flag ? Color.white : Faded);
			GUI.Label(val, flag ? Pretty(_page[_picked]) : "Release to cancel", _titleStyle);
			int num2 = PageCount();
			string text = ((num2 > 1) ? $"Page {_pageIndex + 1}/{num2}   Scroll to turn   -   Right click to favourite" : "Right click to favourite");
			Rect val2 = default(Rect);
			((Rect)(ref val2))..ctor(centre.x - num * 0.5f, centre.y + 10f, num, 22f);
			_hintStyle.normal.textColor = Faded;
			GUI.Label(val2, text, _hintStyle);
		}

		private static string Pretty(string name)
		{
			if (string.IsNullOrEmpty(name))
			{
				return string.Empty;
			}
			char[] array = name.ToCharArray();
			bool flag = true;
			for (int i = 0; i < array.Length; i++)
			{
				if (flag)
				{
					array[i] = char.ToUpperInvariant(array[i]);
				}
				flag = array[i] == ' ';
			}
			return new string(array);
		}

		private static Rect Grow(Rect r, float by)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			return new Rect(((Rect)(ref r)).x - by, ((Rect)(ref r)).y - by, ((Rect)(ref r)).width + by * 2f, ((Rect)(ref r)).height + by * 2f);
		}

		private void DrawEdge(Rect r, float thickness)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			GUI.DrawTexture(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, ((Rect)(ref r)).width, thickness), (Texture)(object)_white);
			GUI.DrawTexture(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).yMax - thickness, ((Rect)(ref r)).width, thickness), (Texture)(object)_white);
			GUI.DrawTexture(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, thickness, ((Rect)(ref r)).height), (Texture)(object)_white);
			GUI.DrawTexture(new Rect(((Rect)(ref r)).xMax - thickness, ((Rect)(ref r)).y, thickness, ((Rect)(ref r)).height), (Texture)(object)_white);
		}

		private void EnsureStyles()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			//IL_0095: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Expected O, but got Unknown
			if ((Object)(object)_white == (Object)null)
			{
				_white = new Texture2D(1, 1);
				_white.SetPixel(0, 0, Color.white);
				_white.Apply();
			}
			if (_cardStyle == null)
			{
				Font font = EmoteLoader.GetFont();
				int num = Mathf.RoundToInt((float)Screen.height / 54f);
				_cardStyle = new GUIStyle
				{
					alignment = (TextAnchor)4,
					fontSize = num,
					wordWrap = false,
					clipping = (TextClipping)1
				};
				_titleStyle = new GUIStyle
				{
					alignment = (TextAnchor)4,
					fontSize = Mathf.RoundToInt((float)num * 1.5f)
				};
				_hintStyle = new GUIStyle
				{
					alignment = (TextAnchor)4,
					fontSize = Mathf.RoundToInt((float)num * 0.8f)
				};
				if ((Object)(object)font != (Object)null)
				{
					_cardStyle.font = font;
					_titleStyle.font = font;
					_hintStyle.font = font;
				}
			}
		}
	}
	[HarmonyPatch(typeof(InputManager), "KeyDown")]
	internal static class EmoteWheelScrollPatch
	{
		private static bool Prefix(InputKey key, ref bool __result)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)key != 4 && (int)key != 5)
			{
				return true;
			}
			if ((Object)(object)EmoteWheel.Instance == (Object)null || !EmoteWheel.Instance.Visible)
			{
				return true;
			}
			__result = false;
			return false;
		}
	}
	[HarmonyPatch(typeof(FlashlightController))]
	internal class FlashlightControllerPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("Update")]
		private static bool Update_Prefix(FlashlightController __instance)
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			EmoteSystem emoteSystem = (((Object)(object)__instance.PlayerAvatar != (Object)null) ? ((Component)__instance.PlayerAvatar).GetComponent<EmoteSystem>() : null);
			if ((Object)(object)emoteSystem == (Object)null)
			{
				return true;
			}
			if (emoteSystem.IsEmoting)
			{
				((Renderer)__instance.mesh).enabled = false;
				((Renderer)__instance.meshShadows).enabled = false;
				((Behaviour)__instance.spotlight).enabled = false;
				__instance.halo.enabled = false;
				__instance.LightActive = false;
				emoteSystem.flashlightHeld = true;
				return false;
			}
			if (emoteSystem.flashlightHeld)
			{
				emoteSystem.flashlightHeld = false;
				__instance.currentState = (State)0;
				__instance.hiddenScale = 0f;
				__instance.introRotLerp = 0f;
				__instance.introYLerp = 0f;
				__instance.outroRotLerp = 0f;
				__instance.outroYLerp = 0f;
				__instance.lightOnLerp = 0f;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(PlayerNameChecker))]
	internal class PlayerNameCheckerPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("Update")]
		public static void Update_Prefix(PlayerNameChecker __instance)
		{
			EmoteSystem instance = EmoteSystem.Instance;
			if ((Object)(object)instance != (Object)null && instance.IsEmoting)
			{
				__instance.checkTimer = 0.25f;
			}
		}
	}
	[BepInPlugin("ImGogole.SomeEmotesREPO", "SomeEmotesREPO", "2.0.1")]
	public class SomeEmotesREPO : BaseUnityPlugin
	{
		internal const string DefaultEmoteKey = "F";

		internal static readonly string[] BindableKeys = new string[100]
		{
			"A", "B", "C", "D", "E", "F", "G", "H", "I", "J",
			"K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
			"U", "V", "W", "X", "Y", "Z", "Alpha0", "Alpha1", "Alpha2", "Alpha3",
			"Alpha4", "Alpha5", "Alpha6", "Alpha7", "Alpha8", "Alpha9", "F1", "F2", "F3", "F4",
			"F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "Space", "Return",
			"Backspace", "Tab", "CapsLock", "Escape", "LeftShift", "RightShift", "LeftControl", "RightControl", "LeftAlt", "RightAlt",
			"Insert", "Delete", "Home", "End", "PageUp", "PageDown", "UpArrow", "DownArrow", "LeftArrow", "RightArrow",
			"BackQuote", "Minus", "Equals", "LeftBracket", "RightBracket", "Backslash", "Semicolon", "Quote", "Comma", "Period",
			"Slash", "Keypad0", "Keypad1", "Keypad2", "Keypad3", "Keypad4", "Keypad5", "Keypad6", "Keypad7", "Keypad8",
			"Keypad9", "KeypadPeriod", "KeypadEnter", "KeypadPlus", "KeypadMinus", "KeypadMultiply", "KeypadDivide", "Mouse2", "Mouse3", "Mouse4"
		};

		internal static SomeEmotesREPO Instance { get; private set; } = null;

		internal static ManualLogSource Logger => Instance._logger;

		private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger;

		internal Harmony? Harmony { get; set; }

		internal static ConfigEntry<string> EmoteKey { get; private set; } = null;

		internal static ConfigEntry<float> WheelSensitivity { get; private set; } = null;

		internal static KeyCode EmoteKeyCode { get; private set; } = (KeyCode)102;

		private void Awake()
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			Instance = this;
			((Component)this).gameObject.transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			EmoteKey = ((BaseUnityPlugin)this).Config.Bind<string>("Emote wheel", "Key", "F", new ConfigDescription("Held down to open the emote wheel. F by default, within reach of the movement keys and clear of interact. Mouse2 is the middle button, Mouse3 and Mouse4 the side ones.", (AcceptableValueBase)(object)new AcceptableValueList<string>(BindableKeys), Array.Empty<object>()));
			ReadEmoteKey();
			EmoteKey.SettingChanged += delegate
			{
				ReadEmoteKey();
			};
			WheelSensitivity = ((BaseUnityPlugin)this).Config.Bind<float>("Emote wheel", "Sensitivity", 0.006f, "How far the wheel swings for a given mouse movement. Raise it if reaching the outer emotes takes too much desk.");
			if (!Object.op_Implicit((Object)(object)((Component)this).GetComponent<EmoteWheel>()))
			{
				((Component)this).gameObject.AddComponent<EmoteWheel>();
			}
			if (!Object.op_Implicit((Object)(object)((Component)this).GetComponent<EmoteLoader>()))
			{
				((Component)this).gameObject.AddComponent<EmoteLoader>();
			}
			if (!Object.op_Implicit((Object)(object)((Component)this).GetComponent<EmoteNetwork>()))
			{
				((Component)this).gameObject.AddComponent<EmoteNetwork>();
			}
			Patch();
			Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!");
		}

		private static void ReadEmoteKey()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Invalid comparison between Unknown and I4
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			if (Enum.TryParse<KeyCode>(EmoteKey.Value, ignoreCase: true, out KeyCode result) && (int)result > 0)
			{
				EmoteKeyCode = result;
				return;
			}
			Logger.LogWarning((object)("'" + EmoteKey.Value + "' is not a key this can bind. Falling back to [F]."));
			EmoteKeyCode = (KeyCode)102;
		}

		internal void Patch()
		{
			//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_0021: Expected O, but got Unknown
			//IL_0026: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
				Harmony val2 = val;
				Harmony = val;
			}
			Harmony.PatchAll();
		}

		internal void Unpatch()
		{
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
}
namespace SomeEmotesREPO.Rig
{
	public enum ProxyBone
	{
		Hips,
		Spine1,
		Spine2,
		Neck,
		Head,
		HeadTop,
		ArmLeft,
		HandLeft,
		ArmRight,
		HandRight,
		UpLegLeft,
		KneeLeft,
		FootLeft,
		UpLegRight,
		KneeRight,
		FootRight
	}
	public sealed class EmoteProxyRig : MonoBehaviour
	{
		private AnimationClip? _slot;

		private static readonly string[] BoneNames = new string[16]
		{
			"mixamorig:Hips", "mixamorig:Spine1", "mixamorig:Spine2", "mixamorig:Neck", "mixamorig:Head", "mixamorig:HeadTop_End", "mixamorig:LeftArm", "mixamorig:LeftHand", "mixamorig:RightArm", "mixamorig:RightHand",
			"mixamorig:LeftUpLeg", "mixamorig:LeftLeg", "mixamorig:LeftFoot", "mixamorig:RightUpLeg", "mixamorig:RightLeg", "mixamorig:RightFoot"
		};

		private readonly Transform?[] _bones = (Transform?[])(object)new Transform[BoneNames.Length];

		private Animator _animator = null;

		private AnimatorOverrideController _override = null;

		private bool _visible;

		public Transform Root => ((Component)_animator).transform;

		public string CurrentClip { get; private set; } = string.Empty;

		public Transform? this[ProxyBone bone] => _bones[(int)bone];

		public static EmoteProxyRig? Create(bool visible = false)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = EmoteBundleLoader.LoadAsset<GameObject>("emote.prefab");
			if ((Object)(object)val == (Object)null)
			{
				SomeEmotesREPO.Logger.LogError((object)"[Solver] emote.prefab not found in the bundle.");
				return null;
			}
			GameObject val2 = Object.Instantiate<GameObject>(val, Vector3.zero, Quaternion.identity);
			((Object)val2).name = (visible ? "SomeEmotesREPO Reference Dancer" : "SomeEmotesREPO Proxy Rig");
			EmoteProxyRig emoteProxyRig = val2.AddComponent<EmoteProxyRig>();
			emoteProxyRig._visible = visible;
			if (!emoteProxyRig.Setup())
			{
				Object.Destroy((Object)(object)val2);
				return null;
			}
			return emoteProxyRig;
		}

		public void PlaceAt(Vector3 position, Quaternion rotation)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			((Component)this).transform.SetPositionAndRotation(position, rotation);
		}

		public void ApplyMaterial(Material material)
		{
			if ((Object)(object)material == (Object)null)
			{
				return;
			}
			int num = 0;
			Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				Material[] array = (Material[])(object)new Material[(val.sharedMaterials.Length == 0) ? 1 : val.sharedMaterials.Length];
				for (int j = 0; j < array.Length; j++)
				{
					array[j] = material;
				}
				val.sharedMaterials = array;
				num++;
			}
			SomeEmotesREPO.Logger.LogInfo((object)$"[Solver] Reference dancer painted with '{((Object)material).name}' on {num} renderers.");
		}

		private bool Setup()
		{
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Expected O, but got Unknown
			Animator componentInChildren = ((Component)this).GetComponentInChildren<Animator>();
			if ((Object)(object)componentInChildren == (Object)null)
			{
				SomeEmotesREPO.Logger.LogError((object)"[Solver] The proxy prefab has no Animator.");
				return false;
			}
			_animator = componentInChildren;
			if (!_visible)
			{
				Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val in componentsInChildren)
				{
					val.enabled = false;
				}
				Light[] componentsInChildren2 = ((Component)this).GetComponentsInChildren<Light>(true);
				foreach (Light val2 in componentsInChildren2)
				{
					((Behaviour)val2).enabled = false;
				}
			}
			else
			{
				Transform[] componentsInChildren3 = ((Component)this).GetComponentsInChildren<Transform>(true);
				foreach (Transform val3 in componentsInChildren3)
				{
					((Component)val3).gameObject.SetActive(true);
				}
				int num = 0;
				Renderer[] componentsInChildren4 = ((Component)this).GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val4 in componentsInChildren4)
				{
					val4.enabled = true;
					val4.shadowCastingMode = (ShadowCastingMode)1;
					((Component)val4).gameObject.layer = 0;
					num++;
				}
				SomeEmotesREPO.Logger.LogInfo((object)$"[Solver] Reference dancer built with {num} renderers.");
			}
			_animator.cullingMode = (AnimatorCullingMode)0;
			_animator.applyRootMotion = false;
			_override = new AnimatorOverrideController(_animator.runtimeAnimatorController);
			_animator.runtimeAnimatorController = (RuntimeAnimatorController)(object)_override;
			List<KeyValuePair<AnimationClip, AnimationClip>> list = new List<KeyValuePair<AnimationClip, AnimationClip>>(_override.overridesCount);
			_override.GetOverrides(list);
			_slot = ((list.Count > 0) ? list[0].Key : null);
			if ((Object)(object)_slot == (Object)null)
			{
				SomeEmotesREPO.Logger.LogError((object)"[Solver] The bundle's animator controller holds no clip to swap out, so no emote can play. Its state needs a clip assigned to it.");
				return false;
			}
			SomeEmotesREPO.Logger.LogInfo((object)("[Solver] Emote clips will replace '" + ((Object)_slot).name + "' in the controller."));
			List<string> list2 = new List<string>();
			AnimatorControllerParameter[] parameters = _animator.parameters;
			foreach (AnimatorControllerParameter val5 in parameters)
			{
				list2.Add(val5.name);
			}
			SomeEmotesREPO.Logger.LogInfo((object)("[Solver] Proxy animator: avatar '" + (((Object)(object)_animator.avatar != (Object)null) ? ((Object)_animator.avatar).name : "<none>") + "', " + $"human {_animator.isHuman}, layers {_animator.layerCount}, " + "parameters [" + string.Join(", ", list2.ToArray()) + "]"));
			if (!_animator.isHuman)
			{
				SomeEmotesREPO.Logger.LogError((object)"[Solver] The dancer prefab has no humanoid Avatar, so no emote can play. In Unity, select Emote.prefab, and set the Avatar field on its Animator to the humanoid avatar generated by the model's FBX, then rebuild the bundle.");
				return false;
			}
			List<string> list3 = new List<string>();
			for (int n = 0; n < BoneNames.Length; n++)
			{
				_bones[n] = FindDeep(((Component)this).transform, BoneNames[n]);
				if ((Object)(object)_bones[n] == (Object)null)
				{
					list3.Add(BoneNames[n]);
				}
			}
			if (list3.Count > 0)
			{
				SomeEmotesREPO.Logger.LogError((object)("[Solver] Proxy rig is missing joints: " + string.Join(", ", list3.ToArray())));
				return false;
			}
			return true;
		}

		public bool Play(AnimationClip clip)
		{
			if ((Object)(object)clip == (Object)null)
			{
				return false;
			}
			if ((Object)(object)_slot == (Object)null)
			{
				return false;
			}
			_override[_slot] = clip;
			CurrentClip = ((Object)clip).name;
			_animator.ResetTrigger("StopEmote");
			_animator.SetTrigger("TriggerEmote");
			return true;
		}

		public void Stop()
		{
			if ((Object)(object)_animator != (Object)null)
			{
				_animator.SetTrigger("StopEmote");
			}
			CurrentClip = string.Empty;
		}

		public Vector3 Position(ProxyBone bone)
		{
			//IL_0040: 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_001e: 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)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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_0048: Unknown result type (might be due to invalid IL or missing references)
			Transform val = _bones[(int)bone];
			return ((Object)(object)val == (Object)null) ? Vector3.zero : (Quaternion.Inverse(Root.rotation) * (val.position - Root.position));
		}

		public Vector3 Direction(ProxyBone from, ProxyBone to)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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)
			Transform val = _bones[(int)from];
			Transform val2 = _bones[(int)to];
			if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
			{
				return Vector3.zero;
			}
			Vector3 val3 = val2.position - val.position;
			if (((Vector3)(ref val3)).sqrMagnitude < 1E-08f)
			{
				return Vector3.zero;
			}
			return Quaternion.Inverse(Root.rotation) * ((Vector3)(ref val3)).normalized;
		}

		public float Length(ProxyBone from, ProxyBone to)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			Transform val = _bones[(int)from];
			Transform val2 = _bones[(int)to];
			return ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) ? 0f : Vector3.Distance(val.position, val2.position);
		}

		private static Transform? FindDeep(Transform root, string name)
		{
			if (string.Equals(((Object)root).name, name, StringComparison.Ordinal))
			{
				return root;
			}
			for (int i = 0; i < root.childCount; i++)
			{
				Transform val = FindDeep(root.GetChild(i), name);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return null;
		}
	}
	public sealed class EmoteRigPlayer
	{
		public enum State
		{
			Idle,
			FadingIn,
			Holding,
			FadingOut
		}

		public const float DefaultFadeIn = 0.25f;

		public const float DefaultFadeOut = 0.18f;

		private PlayerAvatar? _avatar;

		private RepoRigBinder? _rig;

		private EmoteProxyRig? _proxy;

		private RepoRigSolver? _solver;

		private EmoteSuppression? _suppression;

		private State _state = State.Idle;

		private float _weight;

		public float FadeInDuration { get; set; } = 0.25f;

		public float FadeOutDuration { get; set; } = 0.18f;

		public State Current => _state;

		public bool Active => _state != State.Idle;

		public bool Playing => _state == State.FadingIn || _state == State.Holding;

		public float Weight => Ease(_weight);

		public string ClipName { get; private set; } = string.Empty;

		public PlayerAvatar? Avatar => _avatar;

		public string LastInterruption { get; private set; } = string.Empty;

		public bool Play(PlayerAvatar avatar, AnimationClip clip, Quaternion? heading = null)
		{
			if ((Object)(object)avatar == (Object)null || (Object)(object)clip == (Object)null)
			{
				return false;
			}
			if ((Object)(object)_avatar != (Object)(object)avatar)
			{
				Cancel("the target changed");
				_avatar = avatar;
				_rig = null;
				_solver = null;
			}
			else if (_rig != null && (Object)(object)_rig.Visuals == (Object)null)
			{
				_rig = null;
				_solver = null;
			}
			RepoRigBinder repoRigBinder = _rig;
			if (repoRigBinder == null)
			{
				PlayerAvatarVisuals val = VisualsOf(avatar);
				if ((Object)(object)val == (Object)null)
				{
					SomeEmotesREPO.Logger.LogWarning((object)"[Emote] That avatar has no PlayerAvatarVisuals yet.");
					return false;
				}
				if (!RepoRigBinder.TryBind(val, out RepoRigBinder binder, out string error) || binder == null)
				{
					SomeEmotesREPO.Logger.LogError((object)("[Emote] Could not bind the avatar rig: " + error));
					return false;
				}
				repoRigBinder = binder;
				_rig = binder;
			}
			EmoteProxyRig emoteProxyRig = _proxy;
			if ((Object)(object)emoteProxyRig == (Object)null)
			{
				emoteProxyRig = EmoteProxyRig.Create();
				if ((Object)(object)emoteProxyRig == (Object)null)
				{
					return false;
				}
				_proxy = emoteProxyRig;
			}
			if (_solver == null)
			{
				_solver = new RepoRigSolver(repoRigBinder, emoteProxyRig);
			}
			if (_suppression == null)
			{
				_suppression = EmoteSuppression.Begin(repoRigBinder.Visuals, heading);
			}
			_avatar = avatar;
			emoteProxyRig.Play(clip);
			ClipName = ((Object)clip).name;
			LastInterruption = string.Empty;
			_state = State.FadingIn;
			return true;
		}

		public void Stop()
		{
			if (_state != State.Idle && _state != State.FadingOut)
			{
				_state = State.FadingOut;
			}
		}

		public void Cancel(string reason)
		{
			if (_state != State.Idle)
			{
				LastInterruption = reason;
				_proxy?.Stop();
				_rig?.ResetToRest();
				Release();
			}
		}

		public void Tick(float deltaTime)
		{
			if (_state == State.Idle)
			{
				return;
			}
			string text = InterruptReason();
			if (text != null)
			{
				SomeEmotesREPO.Logger.LogInfo((object)("[Emote] Stopped: " + text + "."));
				Cancel(text);
				return;
			}
			switch (_state)
			{
			case State.FadingIn:
				_weight = Advance(_weight, 1f, FadeInDuration, deltaTime);
				if (_weight >= 1f)
				{
					_state = State.Holding;
				}
				break;
			case State.Holding:
				_weight = 1f;
				break;
			case State.FadingOut:
				_weight = Advance(_weight, 0f, FadeOutDuration, deltaTime);
				if (_weight <= 0f)
				{
					_solver?.ReleaseRoot();
					Release();
					return;
				}
				break;
			}
			float weight = Ease(_weight);
			if (_suppression != null)
			{
				_suppression.Weight = weight;
			}
			if (_solver != null)
			{
				_solver.Weight = weight;
				_solver.Solve();
			}
		}

		public void Dispose()
		{
			Cancel("disposed");
			if ((Object)(object)_proxy != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_proxy).gameObject);
			}
			_proxy = null;
			_solver = null;
		}

		private string? InterruptReason()
		{
			if ((Object)(object)_avatar == (Object)null)
			{
				return "the avatar is gone";
			}
			if (_rig == null || (Object)(object)_rig.Visuals == (Object)null)
			{
				return "the avatar visuals are gone";
			}
			if (_avatar.deadSet)
			{
				return "the player died";
			}
			if (_avatar.isTumbling)
			{
				return "the player is tumbling";
			}
			if (_avatar.isDisabled)
			{
				return "the player was disabled";
			}
			return null;
		}

		private void Release()
		{
			_suppression?.End();
			_suppression = null;
			_weight = 0f;
			_state = State.Idle;
			ClipName = string.Empty;
		}

		private static float Advance(float weight, float target, float duration, float deltaTime)
		{
			return (duration <= 0f) ? target : Mathf.MoveTowards(weight, target, deltaTime / duration);
		}

		private static float Ease(float t)
		{
			return t * t * (3f - 2f * t);
		}

		internal static PlayerAvatarVisuals? VisualsOf(PlayerAvatar? avatar)
		{
			if ((Object)(object)avatar == (Object)null)
			{
				return null;
			}
			if ((Object)(object)avatar.playerAvatarVisuals != (Object)null)
			{
				return avatar.playerAvatarVisuals;
			}
			return ((Object)(object)((Component)avatar).transform.parent != (Object)null) ? ((Component)((Component)avatar).transform.parent).GetComponentInChildren<PlayerAvatarVisuals>() : null;
		}
	}
	public sealed class EmoteSuppression
	{
		private static readonly Dictionary<PlayerAvatarVisuals, EmoteSuppression> Suppressed = new Dictionary<PlayerAvatarVisuals, EmoteSuppression>();

		private readonly PlayerAvatarVisuals _visuals;

		private readonly PlayerAvatarLeftArm? _leftArm;

		private readonly Quaternion _frozenRotation;

		public static bool HoldCodeTransforms { get; set; } = true;

		public float Weight { get; set; } = 1f;

		private EmoteSuppression(PlayerAvatarVisuals visuals, Quaternion? heading)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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)
			_visuals = visuals;
			_leftArm = ((Component)visuals).GetComponentInChildren<PlayerAvatarLeftArm>();
			_frozenRotation = (Quaternion)(((??)heading) ?? ((Component)visuals).transform.rotation);
		}

		public static bool IsActive(PlayerAvatarVisuals visuals)
		{
			return (Object)(object)visuals != (Object)null && Suppressed.ContainsKey(visuals);
		}

		public static EmoteSuppression? Begin(PlayerAvatarVisuals visuals, Quaternion? heading = null)
		{
			if ((Object)(object)visuals == (Object)null)
			{
				return null;
			}
			if (Suppressed.TryGetValue(visuals, out EmoteSuppression value))
			{
				return value;
			}
			Prune();
			EmoteSuppression emoteSuppression = new EmoteSuppression(visuals, heading);
			Suppressed[visuals] = emoteSuppression;
			return emoteSuppression;
		}

		public void End()
		{
			Suppressed.Remove(_visuals);
			if (!((Object)(object)_visuals == (Object)null) && !((Object)(object)_visuals.animator == (Object)null))
			{
				_visuals.animator.speed = 1f;
			}
		}

		private static void Prune()
		{
			List<PlayerAvatarVisuals> list = null;
			foreach (KeyValuePair<PlayerAvatarVisuals, EmoteSuppression> item in Suppressed)
			{
				if ((Object)(object)item.Key == (Object)null)
				{
					if (list == null)
					{
						list = new List<PlayerAvatarVisuals>();
					}
					list.Add(item.Key);
				}
			}
			if (list == null)
			{
				return;
			}
			foreach (PlayerAvatarVisuals item2 in list)
			{
				Suppressed.Remove(item2);
			}
		}

		internal static void Tick(PlayerAvatarVisuals visuals)
		{
			if (Suppressed.Count != 0 && Suppressed.TryGetValue(visuals, out EmoteSuppression value))
			{
				value.Apply();
			}
		}

		private void Apply()
		{
			//IL_0085: 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_0096: 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_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Clamp01(Weight);
			if (num <= 0f)
			{
				return;
			}
			if ((Object)(object)_visuals.animator != (Object)null)
			{
				_visuals.animator.speed = 1f - num;
			}
			if ((Object)(object)_visuals.playerAvatarRightArm != (Object)null)
			{
				_visuals.playerAvatarRightArm.forceBasePoseTimer = 0.5f;
			}
			Quaternion val = Quaternion.Slerp(((Component)_visuals).transform.rotation, _frozenRotation, num);
			((Component)_visuals).transform.rotation = val;
			_visuals.bodySpringTarget = val;
			_visuals.bodySpring.lastRotation = val;
			if (!HoldCodeTransforms)
			{
				return;
			}
			Hold(_visuals.leanTransform, num);
			Hold(_visuals.tiltTransform, num);
			Hold(_visuals.legTwistTransform, num);
			Hold(_visuals.bodyTopUpTransform, num);
			Hold(_visuals.bodyTopSideTransform, num);
			Hold(_visuals.headUpTransform, num);
			Hold(_visuals.headSideTransform, num);
			if ((Object)(object)_leftArm != (Object)null)
			{
				Hold(_leftArm.leftArmTransform, num);
			}
			if ((Object)(object)_visuals.playerAvatarRightArm != (Object)null)
			{
				Hold(_visuals.playerAvatarRightArm.rightArmTransform, num);
				Transform rightArmParentTransform = _visuals.playerAvatarRightArm.rightArmParentTransform;
				Hold(rightArmParentTransform, num);
				if ((Object)(object)rightArmParentTransform != (Object)null)
				{
					rightArmParentTransform.localScale = Vector3.Lerp(rightArmParentTransform.localScale, Vector3.one, num);
				}
			}
		}

		private static void Hold(Transform? t, float weight)
		{
			//IL_002a: 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_001d: 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)
			if (!((Object)(object)t == (Object)null))
			{
				t.localRotation = ((weight >= 1f) ? Quaternion.identity : Quaternion.Slerp(t.localRotation, Quaternion.identity, weight));
			}
		}
	}
	[HarmonyPatch(typeof(PlayerAvatarVisuals), "Update")]
	internal static class EmoteSuppressionUpdatePatch
	{
		private static void Postfix(PlayerAvatarVisuals __instance)
		{
			EmoteSuppression.Tick(__instance);
		}
	}
	public enum RigBone
	{
		Root,
		LegLeftBottom,
		LegLeftTop,
		LegRightBottom,
		LegRightTop,
		BodyBottom,
		BodyBottomScale,
		BodyTop,
		BodyTopScale,
		ArmLeft,
		ArmRight,
		ArmRightScale,
		HeadBottom,
		HeadTop
	}
	public sealed class RepoRigBinder
	{
		public const int BoneCount = 14;

		private static readonly string[] BoneNames = new string[14]
		{
			"ANIM BOT", "ANIM LEG L BOT", "ANIM LEG L TOP", "ANIM LEG R BOT", "ANIM LEG R TOP", "ANIM BODY BOT", "ANIM BODY BOT SCALE", "ANIM BODY TOP", "ANIM BODY TOP SCALE", "ANIM ARM L",
			"ANIM ARM R", "ANIM ARM R SCALE", "ANIM HEAD BOT", "ANIM HEAD TOP"
		};

		private static readonly string[] ReservedNames = new string[6] { "ANIM EYE LEFT", "ANIM EYE RIGHT", "ANIM PUPIL LEFT", "ANIM PUPIL LEFT SCALE", "ANIM PUPIL RIGHT", "ANIM PUPIL RIGHT SCALE" };

		private const string TalkWitnessName = "code_head_top";

		private readonly Transform[] _bones = (Transform[])(object)new Transform[14];

		public PlayerAvatarVisuals Visuals { get; }

		public Transform? TalkWitness { get; private set; }

		public Transform this[RigBone bone] => _bones[(int)bone];

		private RepoRigBinder(PlayerAvatarVisuals visuals)
		{
			Visuals = visuals;
		}

		public static string NameOf(RigBone bone)
		{
			return BoneNames[(int)bone];
		}

		public static bool TryBind(PlayerAvatarVisuals visuals, out RepoRigBinder? binder, out string error)
		{
			binder = null;
			error = string.Empty;
			if ((Object)(object)visuals == (Object)null)
			{
				error = "PlayerAvatarVisuals is null.";
				return false;
			}
			Dictionary<string, Transform> dictionary = new Dictionary<string, Transform>(32, StringComparer.Ordinal);
			List<string> list = new List<string>();
			Collect(((Component)visuals).transform, dictionary, list);
			RepoRigBinder repoRigBinder = new RepoRigBinder(visuals);
			List<string> list2 = new List<string>();
			for (int i = 0; i < 14; i++)
			{
				if (dictionary.TryGetValue(BoneNames[i], out var value))
				{
					repoRigBinder._bones[i] = value;
				}
				else
				{
					list2.Add(BoneNames[i]);
				}
			}
			if (list2.Count > 0)
			{
				error = "missing bones: " + string.Join(", ", list2.ToArray());
				return false;
			}
			if (list.Count > 0)
			{
				error = "ambiguous bone names: " + string.Join(", ", list.ToArray());
				return false;
			}
			dictionary.TryGetValue("code_head_top", out var value2);
			repoRigBinder.TalkWitness = value2;
			binder = repoRigBinder;
			return true;
		}

		private static void Collect(Transform t, Dictionary<string, Transform> found, List<string> duplicates)
		{
			string name = ((Object)t).name;
			if (IsTracked(name))
			{
				if (found.ContainsKey(name))
				{
					duplicates.Add(name);
				}
				else
				{
					found[name] = t;
				}
			}
			for (int i = 0; i < t.childCount; i++)
			{
				Collect(t.GetChild(i), found, duplicates);
			}
		}

		private static bool IsTracked(string name)
		{
			if (name.Length == 0)
			{
				return false;
			}
			if (string.Equals(name, "code_head_top", StringComparison.Ordinal))
			{
				return true;
			}
			if (name[0] != 'A')
			{
				return false;
			}
			for (int i = 0; i < BoneNames.Length; i++)
			{
				if (string.Equals(name, BoneNames[i], StringComparison.Ordinal))
				{
					return true;
				}
			}
			return false;
		}

		public void ResetToRest()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < 14; i++)
			{
				Transform val = _bones[i];
				if (!((Object)(object)val == (Object)null))
				{
					val.localRotation = Quaternion.identity;
					val.localScale = Vector3.one;
					val.localPosition = Vector3.zero;
				}
			}
		}

		public string Describe()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine($"Rig bound on '{((Object)Visuals).name}' ({14} bones)");
			for (int i = 0; i < 14; i++)
			{
				stringBuilder.AppendLine($"  {BoneNames[i],-22} {PathFrom(((Component)Visuals).transform, _bones[i])}");
			}
			stringBuilder.AppendLine(string.Format("  {0,-22} {1}", "code_head_top", ((Object)(object)TalkWitness != (Object)null) ? PathFrom(((Component)Visuals).transform, TalkWitness) : "NOT FOUND (voice head motion cannot be verified)"));
			List<string> list = new List<string>();
			string[] reservedNames = ReservedNames;
			foreach (string text in reservedNames)
			{
				if ((Object)(object)FindByName(((Component)Visuals).transform, text) == (Object)null)
				{
					list.Add(text + " MISSING");
				}
			}
			stringBuilder.Append("  reserved (never written): ");
			stringBuilder.Append((list.Count == 0) ? "all present" : string.Join(", ", list.ToArray()));
			return stringBuilder.ToString();
		}

		private static Transform? FindByName(Transform root, string name)
		{
			if (string.Equals(((Object)root).name, name, StringComparison.Ordinal))
			{
				return root;
			}
			for (int i = 0; i < root.childCount; i++)
			{
				Transform val = FindByName(root.GetChild(i), name);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return null;
		}

		private static string PathFrom(Transform root, Transform? t)
		{
			if ((Object)(object)t == (Object)null)
			{
				return "<null>";
			}
			List<string> list = new List<string>();
			Transform val = t;
			while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)root)
			{
				list.Add(((Object)val).name);
				val = val.parent;
			}
			list.Reverse();
			return string.Join("/", list.ToArray());
		}
	}
	public sealed class RepoRigSolver
	{
		private static readonly RigBone[] LimbBones = new RigBone[4]
		{
			RigBone.ArmLeft,
			RigBone.ArmRight,
			RigBone.LegLeftTop,
			RigBone.LegRightTop
		};

		private readonly RepoRigBinder _rig;

		private readonly EmoteProxyRig _proxy;

		private readonly Vector3[] _restAxis = (Vector3[])(object)new Vector3[14];

		private bool _restAxesMeasured;

		private const float MaxCrouch = 0.45f;

		private Vector3 _rootRestPosition;

		private float _proxyLegLength;

		private float _legScale;

		public float Weight { get; set; } = 1f;

		public RepoRigSolver(RepoRigBinder rig, EmoteProxyRig proxy)
		{
			//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_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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			_rig = rig;
			_proxy = proxy;
			_restAxis[9] = Vector3.forward;
			_restAxis[10] = Vector3.forward;
			_restAxis[2] = Vector3.down;
			_restAxis[4] = Vector3.down;
		}

		public void Solve()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: 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_009d: 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_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: 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_00cc: 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_00d9: 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_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: 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)
			if (!(Weight <= 0f))
			{
				EnsureRestAxes();
				Vector3 rightHint = _proxy.Position(ProxyBone.UpLegRight) - _proxy.Position(ProxyBone.UpLegLeft);
				Vector3 rightHint2 = _proxy.Position(ProxyBone.ArmRight) - _proxy.Position(ProxyBone.ArmLeft);
				Quaternion orientationInCharacterSpace = Frame(_proxy.Position(ProxyBone.Spine1) - _proxy.Position(ProxyBone.Hips), rightHint);
				Quaternion orientationInCharacterSpace2 = Frame(_proxy.Position(ProxyBone.Neck) - _proxy.Position(ProxyBone.Spine1), rightHint2);
				Quaternion orientationInCharacterSpace3 = Frame(_proxy.Position(ProxyBone.HeadTop) - _proxy.Position(ProxyBone.Head), rightHint2);
				OrientTo(RigBone.Root, orientationInCharacterSpace);
				OrientTo(RigBone.BodyBottom, orientationInCharacterSpace);
				OrientTo(RigBone.BodyTop, orientationInCharacterSpace2);
				OrientTo(RigBone.HeadBottom, orientationInCharacterSpace3);
				Crouch();
				Aim(RigBone.ArmLeft, _proxy.Direction(ProxyBone.ArmLeft, ProxyBone.HandLeft));
				Aim(RigBone.ArmRight, _proxy.Direction(ProxyBone.ArmRight, ProxyBone.HandRight));
				Aim(RigBone.LegLeftTop, _proxy.Direction(ProxyBone.UpLegLeft, ProxyBone.FootLeft));
				Aim(RigBone.LegRightTop, _proxy.Direction(ProxyBone.UpLegRight, ProxyBone.FootRight));
			}
		}

		private void Crouch()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: 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)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: 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)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			Transform val = _rig[RigBone.Root];
			if (!((Object)(object)val == (Object)null) && !(_legScale <= 0f))
			{
				float num = Mathf.Min(_proxy.Position(ProxyBone.FootLeft).y, _proxy.Position(ProxyBone.FootRight).y);
				float num2 = _proxy.Position(ProxyBone.Hips).y - num;
				float num3 = Mathf.Clamp((_proxyLegLength - num2) * _legScale, 0f, 0.45f);
				Vector3 val2 = _rootRestPosition + Vector3.down * num3;
				val.localPosition = Vector3.Lerp(_rootRestPosition, val2, Weight);
			}
		}

		public void ReleaseRoot()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (_restAxesMeasured)
			{
				Transform val = _rig[RigBone.Root];
				if ((Object)(object)val != (Object)null)
				{
					val.localPosition = _rootRestPosition;
				}
			}
		}

		private static Quaternion Frame(Vector3 up, Vector3 rightHint)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: 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)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			if (((Vector3)(ref up)).sqrMagnitude < 1E-06f || ((Vector3)(ref rightHint)).sqrMagnitude < 1E-06f)
			{
				return Quaternion.identity;
			}
			up = ((Vector3)(ref up)).normalized;
			Vector3 val = Vector3.Cross(((Vector3)(ref rightHint)).normalized, up);
			if (((Vector3)(ref val)).sqrMagnitude < 1E-06f)
			{
				return Quaternion.identity;
			}
			return Quaternion.LookRotation(((Vector3)(ref val)).normalized, up);
		}

		private void OrientTo(RigBone bone, Quaternion orientationInCharacterSpace)
		{
			//IL_003c: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: 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)
			Transform val = _rig[bone];
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val.parent == (Object)null))
			{
				Quaternion val2 = ((Component)_rig.Visuals).transform.rotation * orientationInCharacterSpace;
				Write(val, Quaternion.Inverse(val.parent.rotation) * val2);
			}
		}

		private void Aim(RigBone bone, Vector3 directionInCharacterSpace)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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_0062: 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_0068: 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_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			if (((Vector3)(ref directionInCharacterSpace)).sqrMagnitude < 1E-06f)
			{
				return;
			}
			Transform val = _rig[bone];
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val.parent == (Object)null))
			{
				Vector3 val2 = ((Component)_rig.Visuals).transform.TransformDirection(directionInCharacterSpace);
				Vector3 val3 = val.parent.InverseTransformDirection(val2);
				if (!(((Vector3)(ref val3)).sqrMagnitude < 1E-06f))
				{
					Write(val, Quaternion.FromToRotation(_restAxis[(int)bone], ((Vector3)(ref val3)).normalized));
				}
			}
		}

		private void EnsureRestAxes()
		{
			//IL_004d: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: 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_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			if (_restAxesMeasured)
			{
				return;
			}
			_restAxesMeasured = true;
			RigBone[] limbBones = LimbBones;
			foreach (RigBone rigBone in limbBones)
			{
				Transform val = _rig[rigBone];
				if (!((Object)(object)val == (Object)null))
				{
					Quaternion localRotation = val.localRotation;
					val.localRotation = Quaternion.identity;
					Renderer val2 = FindMesh(val);
					Vector3 val3;
					if (!((Object)(object)val2 != (Object)null))
					{
						val3 = Vector3.zero;
					}
					else
					{
						Bounds bounds = val2.bounds;
						val3 = val.InverseTransformPoint(((Bounds)(ref bounds)).center);
					}
					Vector3 val4 = val3;
					val.localRotation = localRotation;
					if (((Vector3)(ref val4)).sqrMagnitude < 1E-06f)
					{
						SomeEmotesREPO.Logger.LogWarning((object)("[Solver] No mesh under " + RepoRigBinder.NameOf(rigBone) + "; keeping its fallback axis."));
						continue;
					}
					_restAxis[(int)rigBone] = ((Vector3)(ref val4)).normalized;
					SomeEmotesREPO.Logger.LogInfo((object)$"[Solver] {RepoRigBinder.NameOf(rigBone)} rest axis {_restAxis[(int)rigBone]}");
				}
			}
			MeasureLegScale();
		}

		private void MeasureLegScale()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			Transform val = _rig[RigBone.Root];
			Transform val2 = _rig[RigBone.LegLeftTop];
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null))
			{
				_rootRestPosition = val.localPosition;
				float num = Mathf.Abs(val.InverseTransformPoint(val2.position).y);
				_proxyLegLength = _proxy.Length(ProxyBone.UpLegLeft, ProxyBone.KneeLeft) + _proxy.Length(ProxyBone.KneeLeft, ProxyBone.FootLeft);
				_legScale = ((_proxyLegLength > 0.01f) ? (num / _proxyLegLength) : 0f);
				SomeEmotesREPO.Logger.LogInfo((object)$"[Solver] Leg length: REPO {num:0.000}, dancer {_proxyLegLength:0.000}, scale {_legScale:0.000}");
			}
		}

		private static Renderer? FindMesh(Transform bone)
		{
			for (int i = 0; i < bone.childCount; i++)
			{
				Transform child = bone.GetChild(i);
				if (IsOtherLimb(((Object)child).name))
				{
					continue;
				}
				if (((Object)child).name.StartsWith("mesh_", StringComparison.OrdinalIgnoreCase))
				{
					Renderer component = ((Component)child).GetComponent<Renderer>();
					if ((Object)(object)component != (Object)null)
					{
						return component;
					}
				}
				Renderer val = FindMesh(child);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return null;
		}

		private static bool IsOtherLimb(string name)
		{
			return name.StartsWith("ANIM ", StringComparison.Ordinal) && !name.EndsWith(" SCALE", StringComparison.Ordinal);
		}

		private void Write(Transform t, Quaternion target)
		{
			//IL_0023: 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_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			t.localRotation = ((Weight >= 1f) ? target : Quaternion.Slerp(t.localRotation, target, Weight));
		}
	}
}
namespace SomeEmotesREPO.Utils
{
	public static class ChatReflection
	{
		private static readonly FieldRef<ChatManager, bool> _chatActiveGetter = AccessTools.FieldRefAccess<ChatManager, bool>("chatActive");

		public static bool IsChatActive()
		{
			if ((Object)(object)ChatManager.instance == (Object)null)
			{
				return false;
			}
			return _chatActiveGetter.Invoke(ChatManager.instance);
		}
	}
}