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 _gcHandles = new List(); private static readonly List _openStreams = new List(); 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(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(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(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(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(list.Count); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" clips from '"); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted(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(bundlePath); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("': "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(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(allAssetNames.Length); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" assets in bundle"); } log.LogInfo(val); IntPtr typePtr = IL2CPP.Il2CppObjectBaseToPtr((Il2CppObjectBase)(object)Il2CppType.Of()); IL2CPP.Il2CppObjectBaseToPtr((Il2CppObjectBase)(object)Il2CppType.Of()); 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(assetName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(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(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(i); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("] failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(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(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 _clips = new Dictionary(); private static readonly Dictionary _loopFlags = new Dictionary(); 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 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 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(name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' via state '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' on layer "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" (duration "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(value.length, "F2"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("s, loop="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(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(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(); 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(((runtimeAnimatorController != null) ? ((Object)runtimeAnimatorController).name : null) ?? "null"); } log.LogInfo(val); if ((Object)(object)runtimeAnimatorController != (Object)null) { try { Il2CppReferenceArray 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(((Il2CppArrayBase)(object)animationClips).Length); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" clips:"); } log2.LogInfo(val); foreach (AnimationClip item in (Il2CppArrayBase)(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(((Object)item).name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(item.length, "F2"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("s, "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(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(ex.Message); } log4.LogInfo(val); } } try { int value = new Traverse((object)componentInChildren).Field("_layerIndex").GetValue(); ManualLogSource log5 = Plugin.Log; val = new BepInExInfoLogInterpolatedStringHandler(37, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("CustomAnimation: Emote layer index = "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(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(ex2.Message); } log6.LogInfo(val); } List availableEmotes = EmoteAPI.GetAvailableEmotes(); ManualLogSource log7 = Plugin.Log; val = new BepInExInfoLogInterpolatedStringHandler(33, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("CustomAnimation: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(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(((Object)item2).name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' State='"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(item2.EmoteState); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' ID="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(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(_clips.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" registered custom clips:"); } log9.LogInfo(val); foreach (KeyValuePair clip in _clips) { ManualLogSource log10 = Plugin.Log; val = new BepInExInfoLogInterpolatedStringHandler(8, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(clip.Key); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((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.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(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(); if ((Object)(object)componentInChildren == (Object)null) { return (null, 0); } int item = 0; try { item = new Traverse((object)componentInChildren).Field("_layerIndex").GetValue(); } 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(); if ((Object)(object)componentInChildren == (Object)null) { return; } try { new Traverse((object)componentInChildren).Method(methodName, Array.Empty()).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(methodName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(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(overridesCount); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" clips"); } log.LogInfo(val); List 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(((Object)originalClip).name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' for state '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(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(((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(ex); } log4.LogError(val2); } return null; } } public static class EmoteAPI { private static List _cachedEmotes; private static bool _catalogReady; public static List 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.Instance; if ((Object)(object)instance == (Object)null) { return new List(); } List items = ((Catalog)(object)instance).GetItems(false); if (items == null || items.Count == 0) { return new List(); } _cachedEmotes = new List(); 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(_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(ex.Message); } log2.LogWarning(val3); return new List(); } } 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(); 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(((Object)emote).name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' (ID: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(emote.CatalogID); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", State: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(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(ex.Message); } log2.LogWarning(val2); return false; } } public static bool PlayEmoteByIndex(int index) { List availableEmotes = GetAvailableEmotes(); if (index < 0 || index >= availableEmotes.Count) { return false; } return PlayEmote(availableEmotes[index]); } public static bool PlayEmoteByCatalogId(short catalogId) { try { Emote val = Catalog.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(); 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(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(); 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(); if ((Object)(object)componentInChildren == (Object)null) { return; } try { new Traverse((object)componentInChildren).Method("SetFirstPerson", Array.Empty()).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(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 _emotes = new List(); private List _entries = new List(); 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 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.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 WheelToggleKey; internal static ConfigEntry ThirdPersonOnEmote; internal static ConfigEntry RestoreFirstPersonOnExit; internal static ConfigEntry WheelInnerRadius; internal static ConfigEntry WheelOuterRadius; internal static ConfigEntry WheelSlotsPerPage; internal static ConfigEntry WheelScrollCooldownSeconds; internal static ConfigEntry WheelCloseOnSelect; internal static ConfigEntry WheelShowHotkeyBadges; internal static ConfigEntry StopEmoteKey; internal static ConfigEntry[] EmoteHotkeys = new ConfigEntry[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("Wheel", "ToggleKey", (KeyCode)101, "Hold this key to open the emote wheel. Release while hovering to play."); WheelInnerRadius = ((BasePlugin)this).Config.Bind("Wheel", "InnerRadius", 90f, new ConfigDescription("Inner (deadzone) radius of the emote wheel in pixels.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 200f), Array.Empty())); WheelOuterRadius = ((BasePlugin)this).Config.Bind("Wheel", "OuterRadius", 250f, new ConfigDescription("Outer radius of the emote wheel in pixels.", (AcceptableValueBase)(object)new AcceptableValueRange(150f, 500f), Array.Empty())); WheelSlotsPerPage = ((BasePlugin)this).Config.Bind("Wheel", "SlotsPerPage", 8, new ConfigDescription("Number of emote slots shown on a single wheel page. Additional emotes paginate.", (AcceptableValueBase)(object)new AcceptableValueRange(4, 16), Array.Empty())); WheelScrollCooldownSeconds = ((BasePlugin)this).Config.Bind("Wheel", "ScrollCooldownSeconds", 0.15f, new ConfigDescription("Seconds between scroll-wheel page flips.", (AcceptableValueBase)(object)new AcceptableValueRange(0.05f, 0.5f), Array.Empty())); WheelCloseOnSelect = ((BasePlugin)this).Config.Bind("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("Wheel", "ShowHotkeyBadges", true, "Show the configured hotkey label under each emote name in the wheel."); ThirdPersonOnEmote = ((BasePlugin)this).Config.Bind("Camera", "ThirdPersonOnEmote", true, "Switch to third person when playing an emote. Set to false to stay in first person."); RestoreFirstPersonOnExit = ((BasePlugin)this).Config.Bind("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("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("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(); 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(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()).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(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(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; } } }