Decompiled source of EmoteLib v1.1.0

plugins/EmoteLib.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using Emotes;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.IO;
using Microsoft.CodeAnalysis;
using Player;
using Player.Minigame;
using UnityEngine;
using WallyBox;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("EmoteLib")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("EmoteLib")]
[assembly: AssemblyTitle("EmoteLib")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NativeIntegerAttribute : Attribute
	{
		public readonly bool[] TransformFlags;

		public NativeIntegerAttribute()
		{
			TransformFlags = new bool[1] { true };
		}

		public NativeIntegerAttribute(bool[] P_0)
		{
			TransformFlags = P_0;
		}
	}
}
namespace EmoteLib
{
	public static class AssetBundleLoader
	{
		private static readonly FieldInfo LoadFromStreamInjectedDelegateField = typeof(AssetBundle).GetField("LoadFromStreamInternal_InjectedDelegateField", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo LoadAssetWithSubAssetsInjectedDelegateField = typeof(AssetBundle).GetField("LoadAssetWithSubAssets_Internal_InjectedDelegateField", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo LoadAssetInjectedDelegateField = typeof(AssetBundle).GetField("LoadAsset_Internal_InjectedDelegateField", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo GetAllAssetNamesInjectedDelegateField = typeof(AssetBundle).GetField("GetAllAssetNames_InjectedDelegateField", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly List<nint> _gcHandles = new List<IntPtr>();

		private static readonly List<FileStream> _openStreams = new List<FileStream>();

		public static int LoadAndRegisterClips(string bundlePath, ManualLogSource log = null)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			if (log == null)
			{
				log = Plugin.Log;
			}
			List<(string, AnimationClip)> list = LoadClipsFromBundle(bundlePath, log);
			bool flag = default(bool);
			foreach (var (text, clip) in list)
			{
				CustomAnimationPlayer.RegisterClip(text, clip);
				ManualLogSource obj = log;
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(54, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("AssetBundleLoader: Registered clip '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' with emote wheel");
				}
				obj.LogInfo(val);
			}
			return list.Count;
		}

		public static List<(string name, AnimationClip clip)> LoadClipsFromBundle(string bundlePath, ManualLogSource log = null)
		{
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Expected O, but got Unknown
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Expected O, but got Unknown
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Expected O, but got Unknown
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Expected O, but got Unknown
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			if (log == null)
			{
				log = Plugin.Log;
			}
			List<(string, AnimationClip)> list = new List<(string, AnimationClip)>();
			bool flag = default(bool);
			if (!File.Exists(bundlePath))
			{
				ManualLogSource obj = log;
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(41, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("AssetBundleLoader: Bundle not found at '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(bundlePath);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'");
				}
				obj.LogWarning(val);
				return list;
			}
			try
			{
				FileStream val2 = new FileStream(bundlePath, (FileMode)3, (FileAccess)1, (FileShare)1);
				_openStreams.Add(val2);
				IntPtr intPtr = InvokeLoadFromStreamInjected(val2);
				if (intPtr == IntPtr.Zero)
				{
					log.LogError((object)"AssetBundleLoader: LoadFromStream returned null pointer");
					return list;
				}
				IntPtr intPtr2 = ResolveGcHandle(intPtr);
				_gcHandles.Add(IL2CPP.il2cpp_gchandle_new(intPtr2, false));
				try
				{
					Object val3 = new Object(intPtr2);
					val3.hideFlags = (HideFlags)(val3.hideFlags | 0x20);
				}
				catch (Exception ex)
				{
					ManualLogSource obj2 = log;
					BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(51, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("AssetBundleLoader: Could not set bundle hideFlags: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
					}
					obj2.LogWarning(val);
				}
				IntPtr intPtr3 = IntPtr.Zero;
				try
				{
					intPtr3 = Marshal.ReadIntPtr(intPtr2 + 16);
				}
				catch (Exception ex2)
				{
					ManualLogSource obj3 = log;
					BepInExErrorLogInterpolatedStringHandler val4 = new BepInExErrorLogInterpolatedStringHandler(44, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("AssetBundleLoader: m_CachedPtr read failed: ");
						((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(ex2.Message);
					}
					obj3.LogError(val4);
				}
				if (intPtr3 == IntPtr.Zero)
				{
					log.LogError((object)"AssetBundleLoader: Native AssetBundle pointer is null");
					return list;
				}
				list = LoadClipsFromNativeBundle(intPtr3, intPtr2, log);
				ManualLogSource obj4 = log;
				BepInExInfoLogInterpolatedStringHandler val5 = new BepInExInfoLogInterpolatedStringHandler(40, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("AssetBundleLoader: Loaded ");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<int>(list.Count);
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" clips from '");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(Path.GetFileName(bundlePath));
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("'");
				}
				obj4.LogInfo(val5);
			}
			catch (Exception ex3)
			{
				ManualLogSource obj5 = log;
				BepInExErrorLogInterpolatedStringHandler val4 = new BepInExErrorLogInterpolatedStringHandler(43, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("AssetBundleLoader: Fatal error loading '");
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(bundlePath);
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("': ");
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<Exception>(ex3);
				}
				obj5.LogError(val4);
			}
			return list;
		}

		private static List<(string, AnimationClip)> LoadClipsFromNativeBundle(IntPtr nativePtr, IntPtr objectPtr, ManualLogSource log)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			List<(string, AnimationClip)> list = new List<(string, AnimationClip)>();
			string[] allAssetNames = GetAllAssetNames(objectPtr);
			if (allAssetNames == null || allAssetNames.Length == 0)
			{
				allAssetNames = GetAllAssetNames(nativePtr);
			}
			if (allAssetNames == null || allAssetNames.Length == 0)
			{
				log.LogWarning((object)"AssetBundleLoader: No asset names found in bundle");
				return list;
			}
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(42, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("AssetBundleLoader: Found ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(allAssetNames.Length);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" assets in bundle");
			}
			log.LogInfo(val);
			IntPtr typePtr = IL2CPP.Il2CppObjectBaseToPtr((Il2CppObjectBase)(object)Il2CppType.Of<AnimationClip>());
			IL2CPP.Il2CppObjectBaseToPtr((Il2CppObjectBase)(object)Il2CppType.Of<Object>());
			string[] array = allAssetNames;
			foreach (string assetName in array)
			{
				List<(string, AnimationClip)> list2 = TryLoadSubAssets(objectPtr, assetName, typePtr, log);
				if (list2 == null || list2.Count == 0)
				{
					list2 = TryLoadSubAssets(nativePtr, assetName, typePtr, log);
				}
				if (list2 != null)
				{
					list.AddRange(list2);
					if (list.Count > 0)
					{
						break;
					}
				}
			}
			return list;
		}

		private static string[] GetAllAssetNames(IntPtr selfPtr)
		{
			try
			{
				if (!(GetAllAssetNamesInjectedDelegateField?.GetValue(null) is Delegate @delegate))
				{
					return null;
				}
				object obj = @delegate.GetType().GetMethod("Invoke").Invoke(@delegate, new object[1] { selfPtr });
				if (obj is IntPtr)
				{
					IntPtr intPtr = (IntPtr)obj;
					if (intPtr != IntPtr.Zero)
					{
						return ReadIl2CppStringArray(ResolveGcHandle(intPtr));
					}
				}
			}
			catch
			{
			}
			return null;
		}

		private static List<(string, AnimationClip)> TryLoadSubAssets(IntPtr selfPtr, string assetName, IntPtr typePtr, ManualLogSource log)
		{
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			if (!(LoadAssetWithSubAssetsInjectedDelegateField?.GetValue(null) is Delegate @delegate))
			{
				return null;
			}
			try
			{
				MethodInfo? method = @delegate.GetType().GetMethod("Invoke");
				IntPtr intPtr = IL2CPP.ManagedStringToIl2Cpp(assetName);
				object obj = method.Invoke(@delegate, new object[3] { selfPtr, intPtr, typePtr });
				if (obj is IntPtr)
				{
					IntPtr intPtr2 = (IntPtr)obj;
					if (intPtr2 != IntPtr.Zero)
					{
						return ExtractClipsFromArray(intPtr2, log);
					}
				}
			}
			catch (Exception ex)
			{
				Exception ex2 = ex.InnerException ?? ex;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(44, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("AssetBundleLoader: LoadSubAssets '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(assetName);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' failed: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex2.Message);
				}
				log.LogWarning(val);
			}
			return null;
		}

		private static List<(string, AnimationClip)> ExtractClipsFromArray(IntPtr arrayPtr, ManualLogSource log)
		{
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Expected O, but got Unknown
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Expected O, but got Unknown
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Expected O, but got Unknown
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Expected O, but got Unknown
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			List<(string, AnimationClip)> list = new List<(string, AnimationClip)>();
			bool flag = default(bool);
			try
			{
				long num = IL2CPP.il2cpp_array_length(arrayPtr);
				if (num <= 0 || num > 1000)
				{
					return list;
				}
				IntPtr intPtr = arrayPtr + 32;
				for (int i = 0; i < num; i++)
				{
					try
					{
						IntPtr intPtr2 = Marshal.ReadIntPtr(intPtr + IntPtr.Size * i);
						if (!(intPtr2 == IntPtr.Zero) && !(Marshal.PtrToStringUTF8(IL2CPP.il2cpp_class_get_name(IL2CPP.il2cpp_object_get_class(intPtr2))) != "AnimationClip"))
						{
							_gcHandles.Add(IL2CPP.il2cpp_gchandle_new(intPtr2, false));
							AnimationClip val = new AnimationClip(intPtr2);
							try
							{
								((Object)val).hideFlags = (HideFlags)(((Object)val).hideFlags | 0x20);
							}
							catch
							{
							}
							string text = "?";
							try
							{
								text = ((Object)val).name;
							}
							catch
							{
							}
							list.Add((text, val));
							BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(36, 1, ref flag);
							if (flag)
							{
								((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("AssetBundleLoader: Extracted clip '");
								((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text);
								((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'");
							}
							log.LogInfo(val2);
						}
					}
					catch (Exception ex)
					{
						BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(44, 2, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("AssetBundleLoader: Array element [");
							((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(i);
							((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("] failed: ");
							((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(ex.Message);
						}
						log.LogWarning(val3);
					}
				}
			}
			catch (Exception ex2)
			{
				BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(40, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("AssetBundleLoader: ExtractClips failed: ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(ex2.Message);
				}
				log.LogWarning(val3);
			}
			return list;
		}

		private static IntPtr InvokeLoadFromStreamInjected(FileStream stream)
		{
			if (LoadFromStreamInjectedDelegateField == null)
			{
				return IntPtr.Zero;
			}
			Delegate @delegate = LoadFromStreamInjectedDelegateField.GetValue(null) as Delegate;
			if ((object)@delegate == null)
			{
				try
				{
					AssetBundle.LoadFromStream((Stream)(object)stream);
				}
				catch
				{
				}
				try
				{
					((Stream)stream).Seek(0L, (SeekOrigin)0);
				}
				catch
				{
				}
				@delegate = LoadFromStreamInjectedDelegateField.GetValue(null) as Delegate;
			}
			if ((object)@delegate == null)
			{
				return IntPtr.Zero;
			}
			MethodInfo? method = @delegate.GetType().GetMethod("Invoke");
			IntPtr intPtr = IL2CPP.Il2CppObjectBaseToPtr((Il2CppObjectBase)(object)stream);
			object obj3 = method.Invoke(@delegate, new object[3] { intPtr, 0u, 0u });
			if (obj3 is IntPtr)
			{
				return (IntPtr)obj3;
			}
			return IntPtr.Zero;
		}

		private static IntPtr ResolveGcHandle(IntPtr ptr)
		{
			try
			{
				IntPtr intPtr = IL2CPP.il2cpp_gchandle_get_target(ptr);
				if (intPtr != IntPtr.Zero && intPtr != ptr)
				{
					return intPtr;
				}
			}
			catch
			{
			}
			return ptr;
		}

		private static string[] ReadIl2CppStringArray(IntPtr arrayPtr)
		{
			try
			{
				if (arrayPtr == IntPtr.Zero)
				{
					return null;
				}
				if (Marshal.ReadIntPtr(arrayPtr) == IntPtr.Zero)
				{
					return null;
				}
				long num;
				try
				{
					num = IL2CPP.il2cpp_array_length(arrayPtr);
				}
				catch
				{
					int num2 = Marshal.ReadInt32(arrayPtr + 24);
					num = ((num2 > 0 && num2 < 10000) ? num2 : (-1));
				}
				if (num <= 0 || num > 10000)
				{
					return null;
				}
				IntPtr intPtr = arrayPtr + 32;
				string[] array = new string[num];
				for (int i = 0; i < num; i++)
				{
					try
					{
						IntPtr intPtr2 = Marshal.ReadIntPtr(intPtr + IntPtr.Size * i);
						array[i] = ((intPtr2 != IntPtr.Zero) ? IL2CPP.Il2CppStringToManaged(intPtr2) : "(null)");
					}
					catch
					{
						array[i] = "(error)";
					}
				}
				return array;
			}
			catch
			{
				return null;
			}
		}
	}
	public static class CustomAnimationPlayer
	{
		private static readonly Dictionary<string, AnimationClip> _clips = new Dictionary<string, AnimationClip>();

		private static readonly Dictionary<string, bool> _loopFlags = new Dictionary<string, bool>();

		private static RuntimeAnimatorController _originalController;

		private static AnimatorOverrideController _activeOverride;

		private static string _playing;

		private static float _playStartTime;

		private static float _currentClipDuration;

		public static int ClipCount => _clips.Count;

		public static bool IsPlaying => _playing != null;

		public static string CurrentClip => _playing;

		public static void RegisterClip(string name, AnimationClip clip, bool? loop = null)
		{
			if (!((Object)(object)clip == (Object)null) && !string.IsNullOrEmpty(name))
			{
				_clips[name] = clip;
				_loopFlags[name] = loop ?? ((Motion)clip).isLooping;
			}
		}

		public static string[] GetClipNames()
		{
			string[] array = new string[_clips.Count];
			_clips.Keys.CopyTo(array, 0);
			return array;
		}

		public static AnimationClip GetClipByIndex(int index)
		{
			if (index < 0)
			{
				return null;
			}
			int num = 0;
			foreach (KeyValuePair<string, AnimationClip> clip in _clips)
			{
				if (num == index)
				{
					return clip.Value;
				}
				num++;
			}
			return null;
		}

		public static string GetClipNameByIndex(int index)
		{
			if (index < 0)
			{
				return null;
			}
			int num = 0;
			foreach (KeyValuePair<string, AnimationClip> clip in _clips)
			{
				if (num == index)
				{
					return clip.Key;
				}
				num++;
			}
			return null;
		}

		public static bool Play(string name)
		{
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Expected O, but got Unknown
			if (!_clips.TryGetValue(name, out var value))
			{
				return false;
			}
			var (val, num) = GetAnimatorAndLayer();
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			Stop();
			_originalController = val.runtimeAnimatorController;
			if ((Object)(object)_originalController == (Object)null)
			{
				return false;
			}
			_activeOverride = CreateOverrideController(_originalController);
			if ((Object)(object)_activeOverride == (Object)null)
			{
				Plugin.Log.LogError((object)"CustomAnimation: Failed to create AnimatorOverrideController");
				_originalController = null;
				return false;
			}
			string text = FindAndApplyOverride(value);
			if (text == null)
			{
				Stop();
				return false;
			}
			val.runtimeAnimatorController = (RuntimeAnimatorController)(object)_activeOverride;
			val.Play(text, num);
			_playing = name;
			_playStartTime = Time.time;
			_currentClipDuration = value.length;
			if (Plugin.ThirdPersonOnEmote.Value)
			{
				CallEmoteCamera("SetThirdPerson");
			}
			bool value2;
			bool flag = _loopFlags.TryGetValue(name, out value2) && value2;
			ManualLogSource log = Plugin.Log;
			bool flag2 = default(bool);
			BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(70, 5, ref flag2);
			if (flag2)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("CustomAnimation: Playing '");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(name);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' via state '");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' on layer ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(num);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" (duration ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<float>(value.length, "F2");
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("s, loop=");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<bool>(flag);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(")");
			}
			log.LogInfo(val2);
			return true;
		}

		public static void Tick()
		{
			if (_playing != null && !(_loopFlags.TryGetValue(_playing, out var value) && value) && !(_currentClipDuration <= 0f) && Time.time - _playStartTime >= _currentClipDuration)
			{
				Stop();
			}
		}

		public static bool PlayByIndex(int index)
		{
			string clipNameByIndex = GetClipNameByIndex(index);
			if (clipNameByIndex != null)
			{
				return Play(clipNameByIndex);
			}
			return false;
		}

		public static void Stop()
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			if ((Object)(object)_originalController == (Object)null)
			{
				return;
			}
			var (val, num) = GetAnimatorAndLayer();
			if ((Object)(object)val != (Object)null)
			{
				try
				{
					val.runtimeAnimatorController = _originalController;
					val.Play("Idle", num);
				}
				catch (Exception ex)
				{
					ManualLogSource log = Plugin.Log;
					bool flag = default(bool);
					BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(45, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("CustomAnimation: Error restoring controller: ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
					}
					log.LogWarning(val2);
				}
			}
			if (Plugin.ThirdPersonOnEmote.Value)
			{
				CallEmoteCamera("SetFirstPerson");
			}
			_originalController = null;
			_activeOverride = null;
			_playing = null;
			_playStartTime = 0f;
			_currentClipDuration = 0f;
		}

		public static void LogDebugInfo()
		{
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Expected O, but got Unknown
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Expected O, but got Unknown
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Expected O, but got Unknown
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Expected O, but got Unknown
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Expected O, but got Unknown
			//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ec: Expected O, but got Unknown
			//IL_0368: Unknown result type (might be due to invalid IL or missing references)
			//IL_036f: Expected O, but got Unknown
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Expected O, but got Unknown
			//IL_03c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cd: Expected O, but got Unknown
			PlayerInfo localPlayer = PlayerInfo.LocalPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				Plugin.Log.LogInfo((object)"CustomAnimation: No local player");
				return;
			}
			EmotingController componentInChildren = ((Component)localPlayer).GetComponentInChildren<EmotingController>();
			if ((Object)(object)componentInChildren == (Object)null)
			{
				Plugin.Log.LogInfo((object)"CustomAnimation: No EmotingController");
				return;
			}
			Animator animator = componentInChildren.Animator;
			if ((Object)(object)animator == (Object)null)
			{
				Plugin.Log.LogInfo((object)"CustomAnimation: No Animator");
				return;
			}
			RuntimeAnimatorController runtimeAnimatorController = animator.runtimeAnimatorController;
			ManualLogSource log = Plugin.Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(30, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("CustomAnimation: Controller = ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((runtimeAnimatorController != null) ? ((Object)runtimeAnimatorController).name : null) ?? "null");
			}
			log.LogInfo(val);
			if ((Object)(object)runtimeAnimatorController != (Object)null)
			{
				try
				{
					Il2CppReferenceArray<AnimationClip> animationClips = runtimeAnimatorController.animationClips;
					if (animationClips != null)
					{
						ManualLogSource log2 = Plugin.Log;
						val = new BepInExInfoLogInterpolatedStringHandler(9, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("  ");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(((Il2CppArrayBase<AnimationClip>)(object)animationClips).Length);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" clips:");
						}
						log2.LogInfo(val);
						foreach (AnimationClip item in (Il2CppArrayBase<AnimationClip>)(object)animationClips)
						{
							if ((Object)(object)item != (Object)null)
							{
								ManualLogSource log3 = Plugin.Log;
								val = new BepInExInfoLogInterpolatedStringHandler(15, 3, ref flag);
								if (flag)
								{
									((BepInExLogInterpolatedStringHandler)val).AppendLiteral("    '");
									((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Object)item).name);
									((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' (");
									((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(item.length, "F2");
									((BepInExLogInterpolatedStringHandler)val).AppendLiteral("s, ");
									((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(item.frameRate);
									((BepInExLogInterpolatedStringHandler)val).AppendLiteral("fps)");
								}
								log3.LogInfo(val);
							}
						}
					}
				}
				catch (Exception ex)
				{
					ManualLogSource log4 = Plugin.Log;
					val = new BepInExInfoLogInterpolatedStringHandler(29, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("  Could not enumerate clips: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
					}
					log4.LogInfo(val);
				}
			}
			try
			{
				int value = new Traverse((object)componentInChildren).Field("_layerIndex").GetValue<int>();
				ManualLogSource log5 = Plugin.Log;
				val = new BepInExInfoLogInterpolatedStringHandler(37, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("CustomAnimation: Emote layer index = ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(value);
				}
				log5.LogInfo(val);
			}
			catch (Exception ex2)
			{
				ManualLogSource log6 = Plugin.Log;
				val = new BepInExInfoLogInterpolatedStringHandler(38, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("CustomAnimation: Could not get layer: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex2.Message);
				}
				log6.LogInfo(val);
			}
			List<Emote> availableEmotes = EmoteAPI.GetAvailableEmotes();
			ManualLogSource log7 = Plugin.Log;
			val = new BepInExInfoLogInterpolatedStringHandler(33, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("CustomAnimation: ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(availableEmotes.Count);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" catalog emotes:");
			}
			log7.LogInfo(val);
			foreach (Emote item2 in availableEmotes)
			{
				ManualLogSource log8 = Plugin.Log;
				val = new BepInExInfoLogInterpolatedStringHandler(17, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("  '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Object)item2).name);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' State='");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(item2.EmoteState);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' ID=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<short>(item2.CatalogID);
				}
				log8.LogInfo(val);
			}
			ManualLogSource log9 = Plugin.Log;
			val = new BepInExInfoLogInterpolatedStringHandler(42, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("CustomAnimation: ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(_clips.Count);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" registered custom clips:");
			}
			log9.LogInfo(val);
			foreach (KeyValuePair<string, AnimationClip> clip in _clips)
			{
				ManualLogSource log10 = Plugin.Log;
				val = new BepInExInfoLogInterpolatedStringHandler(8, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("  '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(clip.Key);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' (");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Object)(object)clip.Value != (Object)null) ? clip.Value.length.ToString("F2") : "?");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("s)");
				}
				log10.LogInfo(val);
			}
		}

		private static AnimatorOverrideController CreateOverrideController(RuntimeAnimatorController baseController)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0017: Expected O, but got Unknown
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			try
			{
				AnimatorOverrideController val = new AnimatorOverrideController(IL2CPP.il2cpp_object_new(Il2CppClassPointerStore<AnimatorOverrideController>.NativeClassPtr));
				AnimatorOverrideController.Internal_Create(val, baseController);
				return val;
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(50, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("CustomAnimation: CreateOverrideController failed: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
				}
				log.LogError(val2);
				return null;
			}
		}

		private static (Animator animator, int layer) GetAnimatorAndLayer()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			PlayerInfo localPlayer = PlayerInfo.LocalPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return (null, 0);
			}
			EmotingController componentInChildren = ((Component)localPlayer).GetComponentInChildren<EmotingController>();
			if ((Object)(object)componentInChildren == (Object)null)
			{
				return (null, 0);
			}
			int item = 0;
			try
			{
				item = new Traverse((object)componentInChildren).Field("_layerIndex").GetValue<int>();
			}
			catch
			{
			}
			return (componentInChildren.Animator, item);
		}

		private static void CallEmoteCamera(string methodName)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			PlayerInfo localPlayer = PlayerInfo.LocalPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return;
			}
			EmotingController componentInChildren = ((Component)localPlayer).GetComponentInChildren<EmotingController>();
			if ((Object)(object)componentInChildren == (Object)null)
			{
				return;
			}
			try
			{
				new Traverse((object)componentInChildren).Method(methodName, Array.Empty<object>()).GetValue();
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(26, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("CustomAnimation: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(methodName);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" failed: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val);
			}
		}

		private static string FindAndApplyOverride(AnimationClip customClip)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Expected O, but got Unknown
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Expected O, but got Unknown
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Expected O, but got Unknown
			bool flag = default(bool);
			try
			{
				int overridesCount = _activeOverride.overridesCount;
				ManualLogSource log = Plugin.Log;
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(47, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("CustomAnimation: Override controller has ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(overridesCount);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" clips");
				}
				log.LogInfo(val);
				List<Emote> availableEmotes = EmoteAPI.GetAvailableEmotes();
				if (availableEmotes.Count > 0)
				{
					foreach (Emote item in availableEmotes)
					{
						string emoteState = item.EmoteState;
						if (string.IsNullOrEmpty(emoteState))
						{
							continue;
						}
						for (int i = 0; i < overridesCount; i++)
						{
							AnimationClip originalClip = _activeOverride.GetOriginalClip(i);
							if ((Object)(object)originalClip != (Object)null && ((Object)originalClip).name == emoteState)
							{
								_activeOverride.SetClip(originalClip, customClip, false);
								ManualLogSource log2 = Plugin.Log;
								val = new BepInExInfoLogInterpolatedStringHandler(46, 2, ref flag);
								if (flag)
								{
									((BepInExLogInterpolatedStringHandler)val).AppendLiteral("CustomAnimation: Overrode clip '");
									((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Object)originalClip).name);
									((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' for state '");
									((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(emoteState);
									((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'");
								}
								log2.LogInfo(val);
								return emoteState;
							}
						}
					}
				}
				for (int j = 0; j < overridesCount; j++)
				{
					AnimationClip originalClip2 = _activeOverride.GetOriginalClip(j);
					if ((Object)(object)originalClip2 != (Object)null)
					{
						_activeOverride.SetClip(originalClip2, customClip, false);
						ManualLogSource log3 = Plugin.Log;
						val = new BepInExInfoLogInterpolatedStringHandler(42, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("CustomAnimation: Overrode fallback clip '");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Object)originalClip2).name);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'");
						}
						log3.LogInfo(val);
						return ((Object)originalClip2).name;
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log4 = Plugin.Log;
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(46, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("CustomAnimation: FindAndApplyOverride failed: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
				}
				log4.LogError(val2);
			}
			return null;
		}
	}
	public static class EmoteAPI
	{
		private static List<Emote> _cachedEmotes;

		private static bool _catalogReady;

		public static List<Emote> GetAvailableEmotes()
		{
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Expected O, but got Unknown
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			if (_cachedEmotes != null && _catalogReady)
			{
				return _cachedEmotes;
			}
			bool flag = default(bool);
			try
			{
				EmoteCatalog instance = Catalog<Emote, EmoteCatalog>.Instance;
				if ((Object)(object)instance == (Object)null)
				{
					return new List<Emote>();
				}
				List<Emote> items = ((Catalog<Emote, EmoteCatalog>)(object)instance).GetItems(false);
				if (items == null || items.Count == 0)
				{
					return new List<Emote>();
				}
				_cachedEmotes = new List<Emote>();
				for (int i = 0; i < items.Count; i++)
				{
					Emote val = items[i];
					if ((Object)(object)val != (Object)null)
					{
						_cachedEmotes.Add(val);
					}
				}
				_catalogReady = true;
				ManualLogSource log = Plugin.Log;
				BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(34, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("EmoteLib: Found ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(_cachedEmotes.Count);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" emotes in catalog");
				}
				log.LogInfo(val2);
				return _cachedEmotes;
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = Plugin.Log;
				BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(40, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("EmoteLib: Failed to load emote catalog: ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(ex.Message);
				}
				log2.LogWarning(val3);
				return new List<Emote>();
			}
		}

		public static void RefreshCatalog()
		{
			_cachedEmotes = null;
			_catalogReady = false;
		}

		public static bool PlayEmote(Emote emote)
		{
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			if ((Object)(object)emote == (Object)null)
			{
				return false;
			}
			PlayerInfo localPlayer = PlayerInfo.LocalPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				Plugin.Log.LogWarning((object)"EmoteLib: No local player found");
				return false;
			}
			EmotingController componentInChildren = ((Component)localPlayer).GetComponentInChildren<EmotingController>();
			if ((Object)(object)componentInChildren == (Object)null)
			{
				Plugin.Log.LogWarning((object)"EmoteLib: No EmotingController found on local player");
				return false;
			}
			try
			{
				componentInChildren.PlayEmote(emote);
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(42, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EmoteLib: Playing emote '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Object)emote).name);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' (ID: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<short>(emote.CatalogID);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", State: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(emote.EmoteState);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")");
				}
				log.LogInfo(val);
				return true;
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = Plugin.Log;
				bool flag2 = default(bool);
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(32, 1, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("EmoteLib: Failed to play emote: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
				}
				log2.LogWarning(val2);
				return false;
			}
		}

		public static bool PlayEmoteByIndex(int index)
		{
			List<Emote> availableEmotes = GetAvailableEmotes();
			if (index < 0 || index >= availableEmotes.Count)
			{
				return false;
			}
			return PlayEmote(availableEmotes[index]);
		}

		public static bool PlayEmoteByCatalogId(short catalogId)
		{
			try
			{
				Emote val = Catalog<Emote, EmoteCatalog>.FromIndex(catalogId);
				if ((Object)(object)val == (Object)null)
				{
					return false;
				}
				return PlayEmote(val);
			}
			catch
			{
				return false;
			}
		}

		public static void StopEmote()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			PlayerInfo localPlayer = PlayerInfo.LocalPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return;
			}
			EmotingController componentInChildren = ((Component)localPlayer).GetComponentInChildren<EmotingController>();
			if ((Object)(object)componentInChildren == (Object)null)
			{
				return;
			}
			try
			{
				componentInChildren.StopEmote();
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(32, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EmoteLib: Failed to stop emote: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val);
			}
		}

		public static bool IsEmoting()
		{
			PlayerInfo localPlayer = PlayerInfo.LocalPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return false;
			}
			EmotingController componentInChildren = ((Component)localPlayer).GetComponentInChildren<EmotingController>();
			if ((Object)(object)componentInChildren == (Object)null)
			{
				return false;
			}
			return componentInChildren.IsEmoting;
		}

		public static void ForceFirstPerson()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			PlayerInfo localPlayer = PlayerInfo.LocalPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return;
			}
			EmotingController componentInChildren = ((Component)localPlayer).GetComponentInChildren<EmotingController>();
			if ((Object)(object)componentInChildren == (Object)null)
			{
				return;
			}
			try
			{
				new Traverse((object)componentInChildren).Method("SetFirstPerson", Array.Empty<object>()).GetValue();
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(35, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EmoteLib: ForceFirstPerson failed: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val);
			}
		}
	}
	public class EmoteWheelComponent : MonoBehaviour
	{
		private struct WheelEntry
		{
			public Emote Emote;

			public string CustomName;

			public int CustomIndex;

			public bool IsCustom => CustomName != null;
		}

		private bool _wheelOpen;

		private List<Emote> _emotes = new List<Emote>();

		private List<WheelEntry> _entries = new List<WheelEntry>();

		private int _hoveredIndex = -1;

		private int _currentPage;

		private float _lastCatalogCheck;

		private float _scrollCooldown;

		private CursorLockMode _savedLockState;

		private bool _savedCursorVisible;

		private const float CenterDeadzone = 55f;

		private const int TexSize = 512;

		private static readonly Color DimOverlay = new Color(0f, 0f, 0f, 0.35f);

		private static readonly Color SegmentNormal = new Color(0.22f, 0.22f, 0.25f, 0.92f);

		private static readonly Color SegmentHover = new Color(0.35f, 0.42f, 0.75f, 0.95f);

		private static readonly Color CustomSegmentNormal = new Color(0.18f, 0.26f, 0.2f, 0.92f);

		private static readonly Color CustomSegmentHover = new Color(0.28f, 0.55f, 0.38f, 0.95f);

		private static readonly Color DividerColor = new Color(0.45f, 0.48f, 0.55f, 0.7f);

		private static readonly Color RimColor = new Color(0.18f, 0.18f, 0.22f, 0.98f);

		private static readonly Color CenterColor = new Color(0.06f, 0.06f, 0.09f, 0.98f);

		private static readonly Color TextBright = new Color(0.95f, 0.95f, 0.98f, 1f);

		private static readonly Color TextDim = new Color(0.6f, 0.62f, 0.72f, 1f);

		private static readonly Color TextAccent = new Color(0.7f, 0.8f, 1f, 1f);

		private static readonly Color PageDotActive = new Color(0.55f, 0.65f, 1f, 1f);

		private static readonly Color PageDotInactive = new Color(0.3f, 0.32f, 0.4f, 0.8f);

		private static readonly Color ArrowNormal = new Color(0.5f, 0.55f, 0.7f, 0.8f);

		private static readonly Color ArrowHover = new Color(0.7f, 0.8f, 1f, 1f);

		private static readonly Color StopColor = new Color(0.9f, 0.4f, 0.35f, 1f);

		private Texture2D _dimTex;

		private Texture2D _wheelTex;

		private Texture2D _dotActiveTex;

		private Texture2D _dotInactiveTex;

		private int _lastRenderedSlots = -1;

		private int _lastRenderedPage = -1;

		private bool _lastRenderedCustomFlags;

		private bool _needsTexRebuild = true;

		private GUIStyle _nameStyle;

		private GUIStyle _nameHoverStyle;

		private GUIStyle _hotkeyStyle;

		private GUIStyle _titleStyle;

		private GUIStyle _pageStyle;

		private GUIStyle _arrowStyle;

		private GUIStyle _arrowHoverStyle;

		private GUIStyle _stopStyle;

		private GUIStyle _hintStyle;

		private bool _stylesInitialized;

		private int _lastCustomClipCount;

		private bool _wasEmoting;

		public static bool IsWheelOpen { get; private set; }

		private static int SlotsPerPage => Plugin.WheelSlotsPerPage?.Value ?? 8;

		private static float OuterRadius => Plugin.WheelOuterRadius?.Value ?? 250f;

		private static float InnerRadius => Plugin.WheelInnerRadius?.Value ?? 90f;

		private int TotalPages => Mathf.Max(1, Mathf.CeilToInt((float)_entries.Count / (float)SlotsPerPage));

		private void RebuildEntries()
		{
			_entries.Clear();
			foreach (Emote emote in _emotes)
			{
				_entries.Add(new WheelEntry
				{
					Emote = emote
				});
			}
			string[] clipNames = CustomAnimationPlayer.GetClipNames();
			for (int i = 0; i < clipNames.Length; i++)
			{
				_entries.Add(new WheelEntry
				{
					CustomName = clipNames[i],
					CustomIndex = i
				});
			}
		}

		private void Update()
		{
			//IL_00a1: 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_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			CustomAnimationPlayer.Tick();
			bool flag = EmoteAPI.IsEmoting();
			if (_wasEmoting && !flag && Plugin.ThirdPersonOnEmote.Value && Plugin.RestoreFirstPersonOnExit.Value && !MinigameTracker.IsSignSpinningActive)
			{
				EmoteAPI.ForceFirstPerson();
			}
			_wasEmoting = flag;
			bool flag2 = false;
			if (_emotes.Count == 0 && Time.time - _lastCatalogCheck > 5f)
			{
				_lastCatalogCheck = Time.time;
				_emotes = EmoteAPI.GetAvailableEmotes();
				flag2 = true;
			}
			int clipCount = CustomAnimationPlayer.ClipCount;
			if (clipCount != _lastCustomClipCount)
			{
				_lastCustomClipCount = clipCount;
				flag2 = true;
			}
			if (flag2)
			{
				RebuildEntries();
			}
			bool key = Input.GetKey(Plugin.WheelToggleKey.Value);
			if (key && !_wheelOpen)
			{
				_wheelOpen = true;
				IsWheelOpen = true;
				if (_emotes.Count == 0)
				{
					_emotes = EmoteAPI.GetAvailableEmotes();
					RebuildEntries();
				}
				_savedLockState = Cursor.lockState;
				_savedCursorVisible = Cursor.visible;
				Cursor.lockState = (CursorLockMode)0;
				Cursor.visible = true;
			}
			else if (!key && _wheelOpen)
			{
				if (_hoveredIndex >= 0)
				{
					int num = _currentPage * SlotsPerPage + _hoveredIndex;
					if (num < _entries.Count)
					{
						PlayEntry(_entries[num]);
					}
				}
				_wheelOpen = false;
				IsWheelOpen = false;
				Cursor.lockState = _savedLockState;
				Cursor.visible = _savedCursorVisible;
			}
			if (_wheelOpen && _entries.Count > 0)
			{
				Vector2 val = default(Vector2);
				((Vector2)(ref val))..ctor((float)Screen.width / 2f, (float)Screen.height / 2f);
				Vector2 val2 = new Vector2(Input.mousePosition.x, (float)Screen.height - Input.mousePosition.y) - val;
				float magnitude = ((Vector2)(ref val2)).magnitude;
				int num2 = _currentPage * SlotsPerPage;
				int num3 = Mathf.Min(num2 + SlotsPerPage, _entries.Count) - num2;
				int num4 = -1;
				if (magnitude > InnerRadius && magnitude < OuterRadius && num3 > 0)
				{
					float num5 = Mathf.Atan2(val2.y, val2.x) * 57.29578f;
					if (num5 < 0f)
					{
						num5 += 360f;
					}
					float num6 = 360f / (float)num3;
					num4 = Mathf.FloorToInt((num5 + 90f) % 360f / num6) % num3;
				}
				if (num4 != _hoveredIndex)
				{
					_hoveredIndex = num4;
					_needsTexRebuild = true;
				}
			}
			if (_wheelOpen && TotalPages > 1 && Time.time > _scrollCooldown)
			{
				float axis = Input.GetAxis("Mouse ScrollWheel");
				float num7 = Plugin.WheelScrollCooldownSeconds?.Value ?? 0.15f;
				if (axis > 0.01f)
				{
					_currentPage = (_currentPage - 1 + TotalPages) % TotalPages;
					_scrollCooldown = Time.time + num7;
					_needsTexRebuild = true;
				}
				else if (axis < -0.01f)
				{
					_currentPage = (_currentPage + 1) % TotalPages;
					_scrollCooldown = Time.time + num7;
					_needsTexRebuild = true;
				}
			}
			HandleHotkeys();
			HandleStopEmoteHotkey();
		}

		private void LateUpdate()
		{
			if (_wheelOpen)
			{
				Cursor.lockState = (CursorLockMode)0;
				Cursor.visible = true;
			}
		}

		private void HandleHotkeys()
		{
			//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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			if (_emotes.Count == 0)
			{
				return;
			}
			for (int i = 0; i < Plugin.EmoteHotkeys.Length && i < _emotes.Count; i++)
			{
				KeyCode value = Plugin.EmoteHotkeys[i].Value;
				if ((int)value != 0 && Input.GetKeyDown(value))
				{
					EmoteAPI.PlayEmote(_emotes[i]);
				}
			}
		}

		private void HandleStopEmoteHotkey()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			ConfigEntry<KeyCode> stopEmoteKey = Plugin.StopEmoteKey;
			KeyCode val = (KeyCode)((stopEmoteKey != null) ? ((int)stopEmoteKey.Value) : 0);
			if ((int)val != 0 && Input.GetKeyDown(val))
			{
				if (CustomAnimationPlayer.IsPlaying)
				{
					CustomAnimationPlayer.Stop();
				}
				if (EmoteAPI.IsEmoting())
				{
					EmoteAPI.StopEmote();
				}
			}
		}

		private void OnGUI()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0311: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0340: Unknown result type (might be due to invalid IL or missing references)
			//IL_0350: Unknown result type (might be due to invalid IL or missing references)
			//IL_036f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			if (!_wheelOpen || _entries.Count == 0)
			{
				return;
			}
			InitStyles();
			GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)_dimTex);
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor((float)Screen.width / 2f, (float)Screen.height / 2f);
			int num = _currentPage * SlotsPerPage;
			int num2 = Mathf.Min(num + SlotsPerPage, _entries.Count) - num;
			float num3 = OuterRadius * 2f + 20f;
			if ((Object)(object)_wheelTex == (Object)null || _needsTexRebuild || num2 != _lastRenderedSlots || _currentPage != _lastRenderedPage)
			{
				RebuildWheelTexture(num2, num);
				_lastRenderedSlots = num2;
				_lastRenderedPage = _currentPage;
				_needsTexRebuild = false;
			}
			GUI.DrawTexture(new Rect(val.x - num3 / 2f, val.y - num3 / 2f, num3, num3), (Texture)(object)_wheelTex);
			for (int i = 0; i < num2; i++)
			{
				int num4 = num + i;
				float num5 = 360f / (float)num2;
				float num6 = (-90f + (float)i * num5 + num5 / 2f) * ((float)Math.PI / 180f);
				float num7 = (InnerRadius + OuterRadius) / 2f;
				Vector2 val2 = val + new Vector2(Mathf.Cos(num6) * num7, Mathf.Sin(num6) * num7);
				bool num8 = _hoveredIndex == i;
				WheelEntry entry = _entries[num4];
				string text = (entry.IsCustom ? FormatCustomName(entry.CustomName) : FormatEmoteName(entry.Emote));
				GUIStyle val3 = (num8 ? _nameHoverStyle : _nameStyle);
				GUI.Label(CenteredRect(val2.x, val2.y, 100f, 36f), text, val3);
				if (!entry.IsCustom && Plugin.WheelShowHotkeyBadges.Value && num4 < Plugin.EmoteHotkeys.Length)
				{
					KeyCode value = Plugin.EmoteHotkeys[num4].Value;
					if ((int)value != 0)
					{
						GUI.Label(CenteredRect(val2.x, val2.y + 20f, 60f, 18f), ((object)(KeyCode)(ref value)).ToString(), _hotkeyStyle);
					}
				}
				if (num8 && Input.GetMouseButtonDown(0))
				{
					PlayEntry(entry);
					if (Plugin.WheelCloseOnSelect.Value)
					{
						_wheelOpen = false;
						IsWheelOpen = false;
						Cursor.lockState = _savedLockState;
						Cursor.visible = _savedCursorVisible;
					}
				}
			}
			if (EmoteAPI.IsEmoting() || CustomAnimationPlayer.IsPlaying)
			{
				GUI.Label(CenteredRect(val.x, val.y - 6f, 90f, 24f), "STOP", _stopStyle);
				GUI.Label(CenteredRect(val.x, val.y + 14f, 100f, 18f), "right-click", _hintStyle);
				if (Input.GetMouseButtonDown(1))
				{
					CustomAnimationPlayer.Stop();
					EmoteAPI.StopEmote();
				}
			}
			else
			{
				GUI.Label(CenteredRect(val.x, val.y, 100f, 28f), "Emotes", _titleStyle);
			}
			if (TotalPages > 1)
			{
				DrawPagination(val);
			}
		}

		private void RebuildWheelTexture(int slotCount, int startIdx)
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_041b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0420: Unknown result type (might be due to invalid IL or missing references)
			//IL_0454: Unknown result type (might be due to invalid IL or missing references)
			//IL_045b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0467: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0488: Unknown result type (might be due to invalid IL or missing references)
			//IL_048f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0497: Unknown result type (might be due to invalid IL or missing references)
			//IL_049e: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_04db: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_050b: Unknown result type (might be due to invalid IL or missing references)
			//IL_051a: Unknown result type (might be due to invalid IL or missing references)
			//IL_051f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_032b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0324: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Unknown result type (might be due to invalid IL or missing references)
			//IL_031c: Unknown result type (might be due to invalid IL or missing references)
			//IL_039d: Unknown result type (might be due to invalid IL or missing references)
			//IL_039f: Unknown result type (might be due to invalid IL or missing references)
			float num = OuterRadius * 2f + 20f;
			int num2 = (int)num;
			int num3 = (int)num;
			float num4 = (float)num2 / 2f;
			float num5 = (float)num3 / 2f;
			float outerRadius = OuterRadius;
			float innerRadius = InnerRadius;
			float num6 = 4f;
			float num7 = 1.5f;
			if ((Object)(object)_wheelTex == (Object)null || ((Texture)_wheelTex).width != num2 || ((Texture)_wheelTex).height != num3)
			{
				if ((Object)(object)_wheelTex != (Object)null)
				{
					Object.Destroy((Object)(object)_wheelTex);
				}
				_wheelTex = new Texture2D(num2, num3, (TextureFormat)4, false);
				((Texture)_wheelTex).filterMode = (FilterMode)1;
				((Object)_wheelTex).hideFlags = (HideFlags)61;
			}
			Color[] array = (Color[])(object)new Color[num2 * num3];
			Color val = default(Color);
			((Color)(ref val))..ctor(0f, 0f, 0f, 0f);
			float num8 = 360f / (float)slotCount;
			for (int i = 0; i < num3; i++)
			{
				for (int j = 0; j < num2; j++)
				{
					float num9 = (float)j - num4;
					float num10 = 0f - ((float)i - num5);
					float num11 = Mathf.Sqrt(num9 * num9 + num10 * num10);
					if (num11 > outerRadius + num6 || num11 < innerRadius - num6)
					{
						array[i * num2 + j] = val;
						continue;
					}
					if (num11 > outerRadius - 1f)
					{
						float num12 = Mathf.Clamp01((outerRadius + num6 - num11) / 2f);
						array[i * num2 + j] = new Color(RimColor.r, RimColor.g, RimColor.b, RimColor.a * num12);
						continue;
					}
					if (num11 < innerRadius + 1f)
					{
						float num13 = Mathf.Clamp01((num11 - innerRadius + num6) / 2f);
						array[i * num2 + j] = new Color(CenterColor.r, CenterColor.g, CenterColor.b, CenterColor.a * num13);
						continue;
					}
					float num14 = Mathf.Atan2(num10, num9) * 57.29578f;
					if (num14 < 0f)
					{
						num14 += 360f;
					}
					float num15 = (num14 + 90f) % 360f;
					int num16 = Mathf.FloorToInt(num15 / num8) % slotCount;
					float num17 = (float)num16 * num8;
					float num18 = num17 + num8;
					float num19 = Mathf.Abs(num15 - num17);
					float num20 = Mathf.Abs(num15 - num18);
					float num21 = Mathf.Min(num19, num20) * ((float)Math.PI / 180f) * num11;
					if (num21 < num7)
					{
						float num22 = Mathf.Clamp01(1f - num21 / num7);
						array[i * num2 + j] = new Color(DividerColor.r, DividerColor.g, DividerColor.b, DividerColor.a * num22);
						continue;
					}
					bool flag = num16 == _hoveredIndex;
					int num23 = startIdx + num16;
					Color val2 = ((num23 >= _entries.Count || !_entries[num23].IsCustom) ? (flag ? SegmentHover : SegmentNormal) : (flag ? CustomSegmentHover : CustomSegmentNormal));
					if (num11 > outerRadius - 3f)
					{
						float num24 = Mathf.Clamp01((outerRadius - 1f - num11) / 2f);
						val2.a *= num24;
					}
					if (num11 < innerRadius + 3f)
					{
						float num25 = Mathf.Clamp01((num11 - innerRadius - 1f) / 2f);
						val2.a *= num25;
					}
					array[i * num2 + j] = val2;
				}
			}
			Color val4 = default(Color);
			for (int k = 0; k < num3; k++)
			{
				for (int l = 0; l < num2; l++)
				{
					float num26 = (float)l - num4;
					float num27 = (float)k - num5;
					float num28 = Mathf.Sqrt(num26 * num26 + num27 * num27);
					if (num28 < innerRadius - num6)
					{
						float num29 = Mathf.Clamp01((innerRadius - num6 - num28 + 2f) / 2f);
						Color val3 = array[k * num2 + l];
						((Color)(ref val4))..ctor(CenterColor.r, CenterColor.g, CenterColor.b, CenterColor.a * num29);
						float num30 = val4.a + val3.a * (1f - val4.a);
						if (num30 > 0f)
						{
							array[k * num2 + l] = new Color((val4.r * val4.a + val3.r * val3.a * (1f - val4.a)) / num30, (val4.g * val4.a + val3.g * val3.a * (1f - val4.a)) / num30, (val4.b * val4.a + val3.b * val3.a * (1f - val4.a)) / num30, num30);
						}
					}
				}
			}
			_wheelTex.SetPixels(Il2CppStructArray<Color>.op_Implicit(array));
			_wheelTex.Apply();
			bool lastRenderedCustomFlags = false;
			for (int m = startIdx; m < startIdx + slotCount && m < _entries.Count; m++)
			{
				if (_entries[m].IsCustom)
				{
					lastRenderedCustomFlags = true;
					break;
				}
			}
			_lastRenderedCustomFlags = lastRenderedCustomFlags;
		}

		private void PlayEntry(WheelEntry entry)
		{
			if (CustomAnimationPlayer.IsPlaying)
			{
				CustomAnimationPlayer.Stop();
			}
			if (entry.IsCustom)
			{
				CustomAnimationPlayer.Play(entry.CustomName);
			}
			else if ((Object)(object)entry.Emote != (Object)null)
			{
				EmoteAPI.PlayEmote(entry.Emote);
			}
		}

		private void DrawPagination(Vector2 center)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: 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)
			//IL_00d7: 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_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: 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_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			float num = center.y + OuterRadius + 28f;
			float num2 = 14f;
			float num3 = (float)TotalPages * num2;
			float num4 = center.x - num3 / 2f + num2 / 2f;
			for (int i = 0; i < TotalPages; i++)
			{
				float num5 = num4 + (float)i * num2;
				Texture2D val = ((i == _currentPage) ? _dotActiveTex : _dotInactiveTex);
				float num6 = ((i == _currentPage) ? 8f : 6f);
				GUI.DrawTexture(new Rect(num5 - num6 / 2f, num - num6 / 2f, num6, num6), (Texture)(object)val);
			}
			float cy = num;
			Rect val2 = CenteredRect(center.x - num3 / 2f - 20f, cy, 20f, 20f);
			Rect val3 = CenteredRect(center.x + num3 / 2f + 20f, cy, 20f, 20f);
			Vector2 val4 = default(Vector2);
			((Vector2)(ref val4))..ctor(Input.mousePosition.x, (float)Screen.height - Input.mousePosition.y);
			bool flag = ((Rect)(ref val2)).Contains(val4);
			bool flag2 = ((Rect)(ref val3)).Contains(val4);
			GUI.Label(val2, "<", flag ? _arrowHoverStyle : _arrowStyle);
			GUI.Label(val3, ">", flag2 ? _arrowHoverStyle : _arrowStyle);
			if (flag && Input.GetMouseButtonDown(0))
			{
				_currentPage = (_currentPage - 1 + TotalPages) % TotalPages;
			}
			if (flag2 && Input.GetMouseButtonDown(0))
			{
				_currentPage = (_currentPage + 1) % TotalPages;
			}
			GUI.Label(CenteredRect(center.x, num + 14f, 80f, 16f), $"{_currentPage + 1} / {TotalPages}", _pageStyle);
			GUI.Label(CenteredRect(center.x, num + 28f, 120f, 14f), "scroll to browse", _hintStyle);
		}

		private string FormatEmoteName(Emote emote)
		{
			if ((Object)(object)emote == (Object)null)
			{
				return "?";
			}
			string text = ((Object)emote).name;
			if (string.IsNullOrEmpty(text))
			{
				text = emote.EmoteState;
			}
			if (string.IsNullOrEmpty(text))
			{
				text = $"#{emote.CatalogID}";
			}
			if (text.Length > 12)
			{
				text = text.Substring(0, 11) + "..";
			}
			return text;
		}

		private string FormatCustomName(string name)
		{
			if (string.IsNullOrEmpty(name))
			{
				return "?";
			}
			if (name.Length > 12)
			{
				name = name.Substring(0, 11) + "..";
			}
			return name;
		}

		private static Rect CenteredRect(float cx, float cy, float w, float h)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			return new Rect(cx - w / 2f, cy - h / 2f, w, h);
		}

		private void InitStyles()
		{
			//IL_0011: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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_0066: 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_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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)
			//IL_00a3: Expected O, but got Unknown
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Expected O, but got Unknown
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: 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)
			//IL_0112: Expected O, but got Unknown
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Expected O, but got Unknown
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Expected O, but got Unknown
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Expected O, but got Unknown
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Expected O, but got Unknown
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Expected O, but got Unknown
			if (!_stylesInitialized)
			{
				_stylesInitialized = true;
				_dimTex = MakeTex(DimOverlay);
				_dotActiveTex = MakeTex(PageDotActive);
				_dotInactiveTex = MakeTex(PageDotInactive);
				GUIStyle val = new GUIStyle(GUI.skin.label)
				{
					alignment = (TextAnchor)4,
					fontSize = 14,
					fontStyle = (FontStyle)1,
					wordWrap = true
				};
				val.normal.textColor = TextBright;
				_nameStyle = val;
				GUIStyle val2 = new GUIStyle(_nameStyle);
				val2.normal.textColor = Color.white;
				_nameHoverStyle = val2;
				GUIStyle val3 = new GUIStyle(GUI.skin.label)
				{
					alignment = (TextAnchor)4,
					fontSize = 11
				};
				val3.normal.textColor = TextAccent;
				_hotkeyStyle = val3;
				GUIStyle val4 = new GUIStyle(GUI.skin.label)
				{
					alignment = (TextAnchor)4,
					fontSize = 18,
					fontStyle = (FontStyle)1
				};
				val4.normal.textColor = TextBright;
				_titleStyle = val4;
				GUIStyle val5 = new GUIStyle(GUI.skin.label)
				{
					alignment = (TextAnchor)4,
					fontSize = 12
				};
				val5.normal.textColor = TextDim;
				_pageStyle = val5;
				GUIStyle val6 = new GUIStyle(GUI.skin.label)
				{
					alignment = (TextAnchor)4,
					fontSize = 20,
					fontStyle = (FontStyle)1
				};
				val6.normal.textColor = ArrowNormal;
				_arrowStyle = val6;
				GUIStyle val7 = new GUIStyle(_arrowStyle);
				val7.normal.textColor = ArrowHover;
				_arrowHoverStyle = val7;
				GUIStyle val8 = new GUIStyle(GUI.skin.label)
				{
					alignment = (TextAnchor)4,
					fontSize = 15,
					fontStyle = (FontStyle)1
				};
				val8.normal.textColor = StopColor;
				_stopStyle = val8;
				GUIStyle val9 = new GUIStyle(GUI.skin.label)
				{
					alignment = (TextAnchor)4,
					fontSize = 11,
					fontStyle = (FontStyle)2
				};
				val9.normal.textColor = TextDim;
				_hintStyle = val9;
			}
		}

		private static Texture2D MakeTex(Color color)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: 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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			Texture2D val = new Texture2D(1, 1);
			val.SetPixel(0, 0, color);
			val.Apply();
			((Object)val).hideFlags = (HideFlags)61;
			return val;
		}
	}
	[BepInPlugin("com.emotelib.roadsideresearch", "EmoteLib", "1.1.0")]
	public class Plugin : BasePlugin
	{
		public const string GUID = "com.emotelib.roadsideresearch";

		public const string Name = "EmoteLib";

		public const string Version = "1.1.0";

		internal static ManualLogSource Log;

		internal static ConfigEntry<KeyCode> WheelToggleKey;

		internal static ConfigEntry<bool> ThirdPersonOnEmote;

		internal static ConfigEntry<bool> RestoreFirstPersonOnExit;

		internal static ConfigEntry<float> WheelInnerRadius;

		internal static ConfigEntry<float> WheelOuterRadius;

		internal static ConfigEntry<int> WheelSlotsPerPage;

		internal static ConfigEntry<float> WheelScrollCooldownSeconds;

		internal static ConfigEntry<bool> WheelCloseOnSelect;

		internal static ConfigEntry<bool> WheelShowHotkeyBadges;

		internal static ConfigEntry<KeyCode> StopEmoteKey;

		internal static ConfigEntry<KeyCode>[] EmoteHotkeys = new ConfigEntry<KeyCode>[8];

		public override void Load()
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Expected O, but got Unknown
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Expected O, but got Unknown
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Expected O, but got Unknown
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Expected O, but got Unknown
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Expected O, but got Unknown
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BasePlugin)this).Log;
			WheelToggleKey = ((BasePlugin)this).Config.Bind<KeyCode>("Wheel", "ToggleKey", (KeyCode)101, "Hold this key to open the emote wheel. Release while hovering to play.");
			WheelInnerRadius = ((BasePlugin)this).Config.Bind<float>("Wheel", "InnerRadius", 90f, new ConfigDescription("Inner (deadzone) radius of the emote wheel in pixels.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 200f), Array.Empty<object>()));
			WheelOuterRadius = ((BasePlugin)this).Config.Bind<float>("Wheel", "OuterRadius", 250f, new ConfigDescription("Outer radius of the emote wheel in pixels.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(150f, 500f), Array.Empty<object>()));
			WheelSlotsPerPage = ((BasePlugin)this).Config.Bind<int>("Wheel", "SlotsPerPage", 8, new ConfigDescription("Number of emote slots shown on a single wheel page. Additional emotes paginate.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(4, 16), Array.Empty<object>()));
			WheelScrollCooldownSeconds = ((BasePlugin)this).Config.Bind<float>("Wheel", "ScrollCooldownSeconds", 0.15f, new ConfigDescription("Seconds between scroll-wheel page flips.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 0.5f), Array.Empty<object>()));
			WheelCloseOnSelect = ((BasePlugin)this).Config.Bind<bool>("Wheel", "CloseOnSelect", true, "If true, left-clicking a slot plays the emote and closes the wheel. If false, the wheel stays open until the toggle key is released.");
			WheelShowHotkeyBadges = ((BasePlugin)this).Config.Bind<bool>("Wheel", "ShowHotkeyBadges", true, "Show the configured hotkey label under each emote name in the wheel.");
			ThirdPersonOnEmote = ((BasePlugin)this).Config.Bind<bool>("Camera", "ThirdPersonOnEmote", true, "Switch to third person when playing an emote. Set to false to stay in first person.");
			RestoreFirstPersonOnExit = ((BasePlugin)this).Config.Bind<bool>("Camera", "RestoreFirstPersonOnExit", true, "When an emote ends, snap the camera back to first person. Set to false to stay in third person after emoting. Only applies when ThirdPersonOnEmote is true.");
			StopEmoteKey = ((BasePlugin)this).Config.Bind<KeyCode>("Hotkeys", "StopEmoteKey", (KeyCode)0, "Global keybind to cancel the currently playing emote without opening the wheel. Set to None to disable.");
			for (int i = 0; i < 8; i++)
			{
				EmoteHotkeys[i] = ((BasePlugin)this).Config.Bind<KeyCode>("Hotkeys", $"EmoteSlot{i + 1}", (KeyCode)0, $"Hotkey for emote slot {i + 1} (set to None to disable)");
			}
			Harmony val = new Harmony("com.emotelib.roadsideresearch");
			val.PatchAll(typeof(LookInputPatch));
			val.PatchAll(typeof(EmoteCameraPatches));
			val.PatchAll(typeof(MinigameTracker));
			PointerBypassPatch.Apply(val, Log);
			((BasePlugin)this).AddComponent<EmoteWheelComponent>();
			ManualLogSource log = Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(39, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("EmoteLib loaded. Hold ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<KeyCode>(WheelToggleKey.Value);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" for emote wheel.");
			}
			log.LogInfo(val2);
		}
	}
	[HarmonyPatch]
	public static class LookInputPatch
	{
		[HarmonyPatch(typeof(PlayerInput), "AccumulateRenderInput")]
		[HarmonyPrefix]
		public static bool SkipAccumulateRender()
		{
			return !EmoteWheelComponent.IsWheelOpen;
		}
	}
	[HarmonyPatch]
	public static class EmoteCameraPatches
	{
		[HarmonyPatch(typeof(EmotingController), "SetThirdPerson")]
		[HarmonyPrefix]
		public static bool SkipThirdPerson()
		{
			if (Plugin.ThirdPersonOnEmote.Value)
			{
				return !MinigameTracker.IsSignSpinningActive;
			}
			return false;
		}

		[HarmonyPatch(typeof(EmotingController), "PlayEmote")]
		[HarmonyPostfix]
		public static void AfterPlayEmote(EmotingController __instance)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.ThirdPersonOnEmote.Value || MinigameTracker.IsSignSpinningActive)
			{
				return;
			}
			try
			{
				new Traverse((object)__instance).Method("SetThirdPerson", Array.Empty<object>()).GetValue();
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(38, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EmoteLib: SetThirdPerson call failed: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val);
			}
		}
	}
	[HarmonyPatch]
	public static class MinigameTracker
	{
		public static bool IsSignSpinningActive { get; private set; }

		[HarmonyPatch(typeof(Spinning), "StartMinigameFunctionality")]
		[HarmonyPostfix]
		public static void OnSpinningStart()
		{
			IsSignSpinningActive = true;
		}

		[HarmonyPatch(typeof(Spinning), "EndMinigameFunctionality")]
		[HarmonyPostfix]
		public static void OnSpinningEnd()
		{
			IsSignSpinningActive = false;
		}

		[HarmonyPatch(typeof(Minigame), "StopGameInstantly", new Type[] { })]
		[HarmonyPostfix]
		public static void OnStopGameInstantly(Minigame __instance)
		{
			if (__instance is Spinning)
			{
				IsSignSpinningActive = false;
			}
		}
	}
	public static class PointerBypassPatch
	{
		private static readonly FieldInfo PooledPtrField = typeof(Il2CppObjectBase).GetField("pooledPtr", BindingFlags.Instance | BindingFlags.NonPublic);

		private static readonly FieldInfo GcHandleField = typeof(Il2CppObjectBase).GetField("myGcHandle", BindingFlags.Instance | BindingFlags.NonPublic);

		private static readonly bool _isGcHandle = PooledPtrField == null && GcHandleField != null;

		private static readonly FieldInfo _field = PooledPtrField ?? GcHandleField;

		public static void Apply(Harmony harmony, ManualLogSource log)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			try
			{
				MethodInfo methodInfo = typeof(Il2CppObjectBase).GetProperty("Pointer", BindingFlags.Instance | BindingFlags.Public)?.GetGetMethod();
				if (methodInfo != null)
				{
					harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(PointerBypassPatch), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					log.LogInfo((object)"EmoteLib: Patched Il2CppObjectBase.Pointer getter");
				}
				else
				{
					log.LogWarning((object)"EmoteLib: Could not find Pointer getter to patch");
				}
			}
			catch (Exception ex)
			{
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(39, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EmoteLib: Pointer bypass patch failed: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				log.LogError(val);
			}
		}

		public static bool Prefix(Il2CppObjectBase __instance, ref IntPtr __result)
		{
			if (_field == null)
			{
				return true;
			}
			try
			{
				object value = _field.GetValue(__instance);
				if (value is IntPtr)
				{
					IntPtr intPtr = (IntPtr)value;
					if (intPtr != IntPtr.Zero)
					{
						if (!_isGcHandle)
						{
							__result = intPtr;
							return false;
						}
						IntPtr intPtr2 = IL2CPP.il2cpp_gchandle_get_target(intPtr);
						if (intPtr2 != IntPtr.Zero)
						{
							__result = intPtr2;
							return false;
						}
					}
				}
			}
			catch
			{
			}
			return true;
		}
	}
}