Decompiled source of se rompio el mod este v1.8.7
plugins/TooManyEmotes.dll
Decompiled 2 years ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Dissonance.Integrations.Unity_NFGO; using GameNetcodeStuff; using HarmonyLib; using LethalCompanyInputUtils.Api; using MoreCompany.Cosmetics; using TMPro; using TooManyEmotes.Config; using TooManyEmotes.Input; using TooManyEmotes.Networking; using TooManyEmotes.Patches; using Unity.Collections; using Unity.Netcode; using UnityEngine; using UnityEngine.AI; using UnityEngine.Animations.Rigging; using UnityEngine.EventSystems; using UnityEngine.Experimental.Rendering; using UnityEngine.InputSystem; using UnityEngine.Rendering; using UnityEngine.Rendering.HighDefinition; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("TooManyEmotes")] [assembly: AssemblyDescription("Mod made by flipf17")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("TooManyEmotes")] [assembly: AssemblyCopyright("Copyright © 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("d6950625-e3a1-4896-a183-87110491bf18")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] namespace TooManyEmotes { [HarmonyPatch] public static class EmoteMenuManager { public static GameObject menuGameObject; public static RectTransform menuTransform; public static CanvasGroup canvasGroup; public static RawImage renderTextureImageUI; public static TextMeshPro swapPageText; public static TextMeshPro currentEmoteText; public static RenderTexture renderTexture; public static Camera renderingCamera; public static GameObject previewPlayerObject; public static SkinnedMeshRenderer previewPlayerMesh; public static Animator previewPlayerAnimator; public static AnimatorOverrideController previewPlayerAnimatorController; public static int playerLayer = LayerMask.NameToLayer("Player"); public static float hoveredAlpha = 0.75f; public static float unhoveredAlpha = 0.75f; public static Color defaultUIColor = new Color(0.3f, 0.3f, 0.3f); public static List<EmoteUIElement> emoteUIElementsList; public static int hoveredEmoteUIIndex = -1; public static int currentPage = 0; public static List<EmoteLoadoutUIElement> emoteLoadoutUIElementsList; public static List<List<UnlockableEmote>> emoteLoadouts; public static Color selectedLoadoutUIColor = new Color(0.2f, 0.2f, 1f); public static int currentLoadoutIndex = -1; public static int hoveredLoadoutUIIndex = -1; public static Vector2 currentThumbstickPosition = Vector2.zero; public static TextMeshProUGUI[] controlTipLines; public static QuickMenuManager quickMenuManager => StartOfRound.Instance?.localPlayerController?.quickMenuManager; public static PlayerControllerB localPlayerController => StartOfRound.Instance?.localPlayerController; public static int playerLayerMask => 1 << playerLayer; public static int hoveredEmoteIndex => (hoveredEmoteUIIndex >= 0) ? (hoveredEmoteUIIndex + 8 * currentPage) : (-1); public static int numPages => (currentLoadoutEmotesList != null) ? (Mathf.Max((currentLoadoutEmotesList.Count - 1) / emoteUIElementsList.Count, 0) + 1) : 0; public static UnlockableEmote previewingEmote => (currentLoadoutEmotesList != null && hoveredEmoteIndex >= 0 && hoveredEmoteIndex < currentLoadoutEmotesList.Count) ? currentLoadoutEmotesList[hoveredEmoteIndex] : null; public static List<UnlockableEmote> currentLoadoutEmotesList => (emoteLoadouts != null && currentLoadoutIndex >= 0 && currentLoadoutIndex < emoteLoadouts.Count) ? emoteLoadouts[currentLoadoutIndex] : null; public static int numLoadouts => emoteLoadouts.Count; public static bool usingController => StartOfRound.Instance.localPlayerUsingController; public static bool isMenuOpen => (Object)(object)menuGameObject != (Object)null && menuGameObject.activeSelf; [HarmonyPatch(typeof(HUDManager), "Start")] [HarmonyPostfix] public static void InitializeUI(HUDManager __instance) { //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) if (!ConfigSettings.disableEmotesForSelf.Value && !((Object)(object)Plugin.radialMenuPrefab == (Object)null)) { menuGameObject = Object.Instantiate<GameObject>(Plugin.radialMenuPrefab, __instance.HUDContainer.transform.parent); menuGameObject.transform.SetAsLastSibling(); ((Object)menuGameObject).name = "EmotesRadialMenu"; menuTransform = menuGameObject.GetComponent<RectTransform>(); renderTextureImageUI = menuGameObject.GetComponentInChildren<RawImage>(); Transform transform = ((Component)((Transform)menuTransform).Find("RadialMenuUI/RadialElements")).transform; swapPageText = ((Component)((Transform)menuTransform).Find("RadialMenuUI/RadialBase/SwapPageText")).GetComponent<TextMeshPro>(); currentEmoteText = ((Component)((Transform)menuTransform).Find("RadialMenuUI/RadialBase/CurrentEmoteText")).GetComponent<TextMeshPro>(); ((TMP_Text)currentEmoteText).text = ""; emoteUIElementsList = new List<EmoteUIElement>(); controlTipLines = (TextMeshProUGUI[])(object)new TextMeshProUGUI[HUDManager.Instance.controlTipLines.Length]; for (int i = 0; i < HUDManager.Instance.controlTipLines.Length; i++) { TextMeshProUGUI val = Object.Instantiate<TextMeshProUGUI>(HUDManager.Instance.controlTipLines[i], ((TMP_Text)HUDManager.Instance.controlTipLines[0]).transform.parent); ((TMP_Text)val).transform.localScale = ((TMP_Text)HUDManager.Instance.controlTipLines[0]).transform.localScale; ((TMP_Text)val).transform.parent = (Transform)(object)menuTransform; ((TMP_Text)val).transform.SetPositionAndRotation(((TMP_Text)HUDManager.Instance.controlTipLines[i]).transform.position, ((TMP_Text)HUDManager.Instance.controlTipLines[i]).transform.rotation); ((TMP_Text)val).text = ""; ((TMP_Text)val).overflowMode = (TextOverflowModes)0; ((TMP_Text)val).enableWordWrapping = false; controlTipLines[i] = val; } currentPage = 0; hoveredEmoteUIIndex = -1; for (int j = 0; j < transform.childCount; j++) { Transform child = transform.GetChild(j); EmoteUIElement item = new EmoteUIElement { uiGameObject = ((Component)child).gameObject, id = j, backgroundImage = ((Component)child).GetComponentInChildren<Image>(), textContainer = ((Component)child).GetComponentInChildren<TextMeshPro>() }; emoteUIElementsList.Add(item); } EmoteLoadoutUIElement.uiCount = 0; Transform transform2 = ((Component)((Transform)menuTransform).Find("RadialMenuUI/EmoteLoadouts")).transform; ((Component)transform2).gameObject.AddComponent<EmoteLoadoutUIContainer>(); emoteLoadoutUIElementsList = new List<EmoteLoadoutUIElement>(); emoteLoadoutUIElementsList.Add(((Component)transform2.GetChild(0)).gameObject.AddComponent<EmoteLoadoutUIElement>()); emoteLoadoutUIElementsList.Add(Object.Instantiate<EmoteLoadoutUIElement>(emoteLoadoutUIElementsList[0], transform2)); emoteLoadoutUIElementsList.Add(Object.Instantiate<EmoteLoadoutUIElement>(emoteLoadoutUIElementsList[0], transform2)); emoteLoadoutUIElementsList.Add(Object.Instantiate<EmoteLoadoutUIElement>(emoteLoadoutUIElementsList[0], transform2)); emoteLoadoutUIElementsList.Add(Object.Instantiate<EmoteLoadoutUIElement>(emoteLoadoutUIElementsList[0], transform2)); emoteLoadoutUIElementsList.Add(Object.Instantiate<EmoteLoadoutUIElement>(emoteLoadoutUIElementsList[0], transform2)); emoteLoadoutUIElementsList.Add(Object.Instantiate<EmoteLoadoutUIElement>(emoteLoadoutUIElementsList[0], transform2)); for (int k = 0; k < emoteLoadoutUIElementsList.Count; k++) { ((Object)emoteLoadoutUIElementsList[k]).name = "EmoteLoadout_" + k; } emoteLoadoutUIElementsList[0].loadoutName = "Favorites"; emoteLoadoutUIElementsList[1].loadoutName = $"<color={UnlockableEmote.rarityColorCodes[3]}>Legendary</color>"; emoteLoadoutUIElementsList[2].loadoutName = $"<color={UnlockableEmote.rarityColorCodes[2]}>Epic</color>"; emoteLoadoutUIElementsList[3].loadoutName = $"<color={UnlockableEmote.rarityColorCodes[1]}>Rare</color>"; emoteLoadoutUIElementsList[4].loadoutName = $"<color={UnlockableEmote.rarityColorCodes[0]}>Common</color>"; emoteLoadoutUIElementsList[5].loadoutName = "Complementary"; emoteLoadoutUIElementsList[6].loadoutName = "All"; SaveManager.LoadFavoritedEmotes(); emoteLoadouts = new List<List<UnlockableEmote>> { StartOfRoundPatcher.unlockedFavoriteEmotes, StartOfRoundPatcher.unlockedEmotesTier3, StartOfRoundPatcher.unlockedEmotesTier2, StartOfRoundPatcher.unlockedEmotesTier1, StartOfRoundPatcher.unlockedEmotesTier0, StartOfRoundPatcher.complementaryEmotes, StartOfRoundPatcher.unlockedEmotes }; if (currentLoadoutIndex < 0 || currentLoadoutIndex >= emoteLoadouts.Count) { currentLoadoutIndex = emoteLoadouts.Count - 1; } InitializeAnimationRenderer(); menuGameObject.SetActive(false); } } [HarmonyPatch(typeof(HUDManager), "Update")] [HarmonyPostfix] public static void GetInput() { //IL_00a9: 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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: 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) if (ConfigSettings.disableEmotesForSelf.Value || (Object)(object)previewPlayerAnimatorController == (Object)null || !isMenuOpen) { return; } if (EmoteLoadoutUIContainer.hovered || hoveredLoadoutUIIndex != -1) { if (hoveredEmoteUIIndex != -1) { OnHoveredNewElement(-1); } return; } Vector2 val3; if (!usingController) { Vector2 val = ((InputControl<Vector2>)(object)((Pointer)Mouse.current).position).ReadValue(); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor((float)(Screen.width / 2), (float)(Screen.height / 2)); val3 = val - val2; } else { val3 = currentThumbstickPosition; } int num = -1; if ((!usingController && ((Vector2)(ref val3)).magnitude / (float)Screen.height >= 0.17f) || (usingController && currentThumbstickPosition != Vector2.zero)) { float num2 = Mathf.Atan2(val3.y, 0f - val3.x) * 57.29578f - 67.5f; if (num2 < 0f) { num2 += 360f; } num = Mathf.FloorToInt(num2 / 45f); } if (num != hoveredEmoteUIIndex) { OnHoveredNewElement(num); } } public static void OnUpdateThumbStickAngle(CallbackContext context) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)localPlayerController == (Object)null) && !ConfigSettings.disableEmotesForSelf.Value && ((CallbackContext)(ref context)).performed && !ConfigSync.instance.syncEnableMovingWhileEmoting && isMenuOpen) { currentThumbstickPosition = ((CallbackContext)(ref context)).ReadValue<Vector2>(); currentThumbstickPosition = ((((Vector2)(ref currentThumbstickPosition)).magnitude > 0.75f) ? currentThumbstickPosition : Vector2.zero); StartOfRound.Instance.localPlayerUsingController = true; if (currentThumbstickPosition == Vector2.zero && previewingEmote != null) { localPlayerController.PerformEmote(context, -(previewingEmote.emoteId + 1)); CloseEmoteMenu(); } } } public static void OnHoveredNewLoadoutElement(int index) { if (hoveredLoadoutUIIndex == index) { return; } hoveredLoadoutUIIndex = index; foreach (EmoteLoadoutUIElement emoteLoadoutUIElements in emoteLoadoutUIElementsList) { emoteLoadoutUIElements.OnHover(emoteLoadoutUIElements.id == index); } } public static void OnHoveredNewElement(int index) { if (hoveredEmoteUIIndex != -1 && hoveredEmoteUIIndex != index) { emoteUIElementsList[hoveredEmoteUIIndex].OnHover(hovered: false); } if (index != -1) { emoteUIElementsList[index].OnHover(); } hoveredEmoteUIIndex = index; SetPreviewAnimation(hoveredEmoteIndex); } public static void SwapPrevPage() { hoveredEmoteUIIndex = -1; currentPage--; currentPage = ((currentPage < 0) ? (numPages - 1) : currentPage); UpdateEmoteWheel(); } public static void SwapNextPage() { hoveredEmoteUIIndex = -1; currentPage = (currentPage + 1) % numPages; UpdateEmoteWheel(); } public static void UpdateControlTipLines() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: 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) int num = (usingController ? 1 : 0); InputBinding val = Keybinds.PrevEmotePageAction.bindings[num]; string displayName = ConfigSettings.GetDisplayName(((InputBinding)(ref val)).overridePath); val = Keybinds.NextEmotePageAction.bindings[num]; string displayName2 = ConfigSettings.GetDisplayName(((InputBinding)(ref val)).overridePath); val = Keybinds.NextEmoteLoadoutUpAction.bindings[num]; string displayName3 = ConfigSettings.GetDisplayName(((InputBinding)(ref val)).overridePath); val = Keybinds.NextEmoteLoadoutDownAction.bindings[num]; string displayName4 = ConfigSettings.GetDisplayName(((InputBinding)(ref val)).overridePath); val = Keybinds.FavoriteEmoteAction.bindings[num]; string displayName5 = ConfigSettings.GetDisplayName(((InputBinding)(ref val)).overridePath); int i = 0; if (!usingController) { ((TMP_Text)controlTipLines[i++]).text = "Swap Page: [Scroll Mouse]"; } else if (displayName != "" || displayName2 != "") { ((TMP_Text)controlTipLines[i++]).text = $"Swap Page: [{displayName}/{displayName2}]"; } if (usingController || displayName3 != "" || displayName4 != "") { ((TMP_Text)controlTipLines[i++]).text = $"Swap Loadout: [{displayName3}/{displayName4}]"; } ((TMP_Text)controlTipLines[i++]).text = $"Favorite Emote: [{displayName5}]"; for (; i < controlTipLines.Length; i++) { ((TMP_Text)controlTipLines[i]).text = ""; } } public static void UpdateEmoteWheel() { //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_017c: 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) currentPage = Mathf.Clamp(currentPage, 0, numPages - 1); ((TMP_Text)swapPageText).text = $"Page [{currentPage + 1} / {numPages}]"; for (int i = 0; i < emoteLoadoutUIElementsList.Count; i++) { EmoteLoadoutUIElement emoteLoadoutUIElement = emoteLoadoutUIElementsList[i]; emoteLoadoutUIElement.OnHover(hoveredLoadoutUIIndex == emoteLoadoutUIElement.id); } for (int j = 0; j < emoteLoadouts.Count; j++) { List<UnlockableEmote> list = emoteLoadouts[j]; EmoteLoadoutUIElement emoteLoadoutUIElement2 = emoteLoadoutUIElementsList[j]; ((TMP_Text)emoteLoadoutUIElement2.textContainer).text = emoteLoadoutUIElement2.loadoutName + " [" + list.Count + "]"; } for (int k = 0; k < emoteUIElementsList.Count; k++) { EmoteUIElement emoteUIElement = emoteUIElementsList[k]; int num = k + 8 * currentPage; ((TMP_Text)emoteUIElement.textContainer).text = ""; emoteUIElement.emote = null; Color baseColor = defaultUIColor; if (num < currentLoadoutEmotesList.Count) { UnlockableEmote unlockableEmote = currentLoadoutEmotesList[num]; if (unlockableEmote != null) { emoteUIElement.emote = unlockableEmote; ((TMP_Text)emoteUIElement.textContainer).text = unlockableEmote.displayName; } } emoteUIElement.baseColor = baseColor; emoteUIElement.OnHover(hovered: false); } if (hoveredEmoteUIIndex >= 0 && hoveredEmoteUIIndex < 8) { OnHoveredNewElement(hoveredEmoteUIIndex); } } public static void SetPreviewAnimation(int emoteIndex) { if (emoteIndex >= 0 && emoteIndex < currentLoadoutEmotesList.Count && currentLoadoutEmotesList[emoteIndex] != null) { UnlockableEmote unlockableEmote = currentLoadoutEmotesList[emoteIndex]; previewPlayerObject.SetActive(true); ((Behaviour)renderingCamera).enabled = true; previewPlayerAnimatorController["EmoteStart"] = unlockableEmote.animationClip; previewPlayerAnimatorController["EmoteLoop"] = (((Object)(object)unlockableEmote.transitionsToClip != (Object)null) ? unlockableEmote.transitionsToClip : null); previewPlayerAnimator.SetBool("hasTransition", (Object)(object)unlockableEmote.transitionsToClip != (Object)null); previewPlayerAnimator.Play("EmoteStart", 0, 0f); ((TMP_Text)currentEmoteText).text = unlockableEmote.displayNameColorCoded + (StartOfRoundPatcher.allFavoriteEmotes.Contains(unlockableEmote.emoteName) ? " *" : ""); } else { previewPlayerAnimatorController["EmoteStart"] = null; previewPlayerAnimatorController["EmoteLoop"] = null; previewPlayerObject.SetActive(false); ((TMP_Text)currentEmoteText).text = ""; DisableRenderCameraNextFrame(); } } public static void DisableRenderCameraNextFrame() { ((MonoBehaviour)HUDManager.Instance).StartCoroutine(DisableRenderCameraNextFrameCoroutine()); static IEnumerator DisableRenderCameraNextFrameCoroutine() { yield return null; ((Behaviour)renderingCamera).enabled = false; } } public static void SetCurrentEmoteLoadout(int loadoutIndex) { if (currentLoadoutIndex != loadoutIndex) { currentPage = 0; currentLoadoutIndex = loadoutIndex; UpdateEmoteWheel(); } } public static void ToggleFavoriteHoveredEmote() { if (isMenuOpen && previewingEmote != null) { string emoteName = previewingEmote.emoteName; if (StartOfRoundPatcher.allFavoriteEmotes.Contains(emoteName)) { StartOfRoundPatcher.allFavoriteEmotes.Remove(emoteName); } else { StartOfRoundPatcher.allFavoriteEmotes.Add(emoteName); } StartOfRoundPatcher.UpdateUnlockedFavoriteEmotes(); SaveManager.SaveFavoritedEmotes(); UpdateEmoteWheel(); } } public static void ToggleEmoteMenu() { if (!isMenuOpen) { OpenEmoteMenu(); } else { CloseEmoteMenu(); } } public static void OpenEmoteMenu() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) menuGameObject.SetActive(true); Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; quickMenuManager.isMenuOpen = true; ((Renderer)previewPlayerMesh).material = ((Renderer)localPlayerController.thisPlayerModel).material; currentThumbstickPosition = Vector2.zero; TextMeshProUGUI[] array = HUDManager.Instance.controlTipLines; foreach (TextMeshProUGUI val in array) { ((Behaviour)val).enabled = false; } UpdateControlTipLines(); UpdateEmoteWheel(); } public static void CloseEmoteMenu() { Cursor.lockState = (CursorLockMode)1; Cursor.visible = false; localPlayerController.isFreeCamera = false; menuGameObject.SetActive(false); quickMenuManager.CloseQuickMenu(); TextMeshProUGUI[] array = HUDManager.Instance.controlTipLines; foreach (TextMeshProUGUI val in array) { ((Behaviour)val).enabled = true; } } public static bool CanOpenEmoteMenu() { if ((quickMenuManager.isMenuOpen && !isMenuOpen) || (Object)(object)previewPlayerObject == (Object)null) { return false; } if (localPlayerController.isPlayerDead || localPlayerController.inTerminalMenu || localPlayerController.isTypingChat || localPlayerController.isPlayerDead || localPlayerController.inSpecialInteractAnimation || localPlayerController.isGrabbingObjectAnimation || localPlayerController.inShockingMinigame || localPlayerController.isClimbingLadder || localPlayerController.isSinking || (Object)(object)localPlayerController.inAnimationWithEnemy != (Object)null || CentipedePatcher.IsCentipedeLatchedOntoLocalPlayer()) { return false; } return true; } private static void InitializeAnimationRenderer() { //IL_0006: 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_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) renderingCamera = new GameObject("AnimationRenderingCamera").AddComponent<Camera>(); Object.Destroy((Object)(object)((Component)renderingCamera).GetComponent<AudioListener>()); renderingCamera.cullingMask = playerLayerMask; renderingCamera.clearFlags = (CameraClearFlags)2; renderingCamera.cameraType = (CameraType)4; renderingCamera.backgroundColor = new Color(0.1f, 0.1f, 0.1f, 0f); renderingCamera.allowHDR = false; renderingCamera.allowMSAA = false; renderingCamera.farClipPlane = 5f; renderTexture = new RenderTexture(1024, 1024, 24); renderTexture.format = (RenderTextureFormat)0; renderTexture.graphicsFormat = (GraphicsFormat)8; renderTexture.depthStencilFormat = (GraphicsFormat)92; renderingCamera.targetTexture = renderTexture; ((Component)renderingCamera).transform.position = Vector3.down * 1000f; renderTextureImageUI.texture = (Texture)(object)renderTexture; Light val = new GameObject("Spotlight").AddComponent<Light>(); val.type = (LightType)0; ((Component)val).transform.position = ((Component)renderingCamera).transform.position; ((Component)val).transform.parent = ((Component)renderingCamera).transform; ((Component)val).transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity); val.intensity = 50f; val.range = 40f; val.innerSpotAngle = 100f; val.spotAngle = 120f; ((Component)val).gameObject.layer = playerLayer; DisableRenderCameraNextFrame(); } [HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")] [HarmonyPostfix] public static void InitializePlayerCloneRenderObject(PlayerControllerB __instance) { if (!ConfigSettings.disableEmotesForSelf.Value && !((Object)(object)Plugin.radialMenuPrefab == (Object)null)) { ((MonoBehaviour)__instance).StartCoroutine(InitPlayerCloneAfterSpawnAnimation()); } IEnumerator InitPlayerCloneAfterSpawnAnimation() { yield return (object)new WaitForSeconds(2f); previewPlayerObject = Object.Instantiate<GameObject>(((Component)__instance).gameObject, ((Component)renderingCamera).transform); ((Object)previewPlayerObject).name = "PreviewPlayerAnimationObject"; GameObject modelGameObject = ((Component)previewPlayerObject.transform.Find("ScavengerModel")).gameObject; GameObject metarigGameObject = ((Component)modelGameObject.transform.Find("metarig")).gameObject; PlayerControllerB copyPlayerController = previewPlayerObject.GetComponentInChildren<PlayerControllerB>(); ((Renderer)copyPlayerController.thisPlayerModel).shadowCastingMode = (ShadowCastingMode)1; previewPlayerMesh = copyPlayerController.thisPlayerModel; Object.DestroyImmediate((Object)(object)modelGameObject.GetComponentInChildren<LODGroup>()); Object.DestroyImmediate((Object)(object)metarigGameObject.GetComponentInChildren<RigBuilder>()); Object.DestroyImmediate((Object)(object)copyPlayerController.playerBodyAnimator); previewPlayerAnimator = metarigGameObject.AddComponent<Animator>(); previewPlayerAnimatorController = new AnimatorOverrideController(Plugin.previewAnimatorController); previewPlayerAnimator.runtimeAnimatorController = (RuntimeAnimatorController)(object)previewPlayerAnimatorController; previewPlayerAnimator.Play("EmoteStart", 0, 0f); Object.DestroyImmediate((Object)(object)previewPlayerObject.GetComponent<NfgoPlayer>()); foreach (Transform item in previewPlayerObject.transform) { Transform child2 = item; if (((Object)child2).name != "ScavengerModel") { Object.Destroy((Object)(object)((Component)child2).gameObject); } } foreach (Transform item2 in modelGameObject.transform) { Transform child3 = item2; if (((Object)child3).name != "LOD1" && ((Object)child3).name != "metarig") { Object.Destroy((Object)(object)((Component)child3).gameObject); } } foreach (Transform item3 in metarigGameObject.transform) { Transform child = item3; if (((Object)child).name != "spine") { Object.Destroy((Object)(object)((Component)child).gameObject); } } List<Component> destroyComponents = new List<Component>((IEnumerable<Component>)(object)previewPlayerObject.GetComponentsInChildren<HDAdditionalLightData>()); destroyComponents.AddRange((IEnumerable<Component>)(object)previewPlayerObject.GetComponentsInChildren<HDAdditionalCameraData>()); destroyComponents.AddRange((IEnumerable<Component>)(object)previewPlayerObject.GetComponentsInChildren<AudioReverbFilter>()); destroyComponents.AddRange((IEnumerable<Component>)(object)previewPlayerObject.GetComponentsInChildren<OccludeAudio>()); destroyComponents.AddRange((IEnumerable<Component>)(object)previewPlayerObject.GetComponentsInChildren<AudioLowPassFilter>()); destroyComponents.AddRange((IEnumerable<Component>)(object)previewPlayerObject.GetComponentsInChildren<AudioHighPassFilter>()); destroyComponents.AddRange((IEnumerable<Component>)(object)previewPlayerObject.GetComponentsInChildren<AudioChorusFilter>()); foreach (Component component2 in destroyComponents) { Object.DestroyImmediate((Object)(object)component2); } Component[] componentsInChildren = previewPlayerObject.GetComponentsInChildren<Component>(); foreach (Component component in componentsInChildren) { if (!(component is Transform) && !(component is SkinnedMeshRenderer) && !(component is MeshFilter) && !(component is Animator)) { try { Object.DestroyImmediate((Object)(object)component); } catch { Plugin.LogError("Failed to destroy component of type: " + ((object)component).GetType().ToString() + " on animation previewer object."); } } } previewPlayerObject.transform.position = ((Component)renderingCamera).transform.position + ((Component)renderingCamera).transform.forward * 2.8f + Vector3.down * 1.35f; previewPlayerObject.transform.LookAt(new Vector3(((Component)renderingCamera).transform.position.x, previewPlayerObject.transform.position.y, ((Component)renderingCamera).transform.position.z)); SetObjectLayerRecursive(previewPlayerObject, playerLayer); } } private static void SetObjectLayerRecursive(GameObject obj, int layer) { if (!((Object)(object)obj == (Object)null)) { obj.layer = layer; for (int i = 0; i < obj.transform.childCount; i++) { Transform child = obj.transform.GetChild(i); SetObjectLayerRecursive((child != null) ? ((Component)child).gameObject : null, layer); } } } [HarmonyPatch(typeof(PlayerControllerB), "ScrollMouse_performed")] [HarmonyPrefix] public static bool OnScrollMouse(CallbackContext context, PlayerControllerB __instance) { if (ConfigSettings.disableEmotesForSelf.Value || (Object)(object)__instance != (Object)(object)localPlayerController || !isMenuOpen || !((CallbackContext)(ref context)).performed || usingController) { return true; } if (numPages == 0 || (numPages == 1 && currentPage == 0)) { return false; } if (((CallbackContext)(ref context)).ReadValue<float>() < 0f && !ConfigSettings.reverseEmoteWheelScrollDirection.Value) { SwapPrevPage(); } else { SwapNextPage(); } return false; } [HarmonyPatch(typeof(PlayerControllerB), "ItemSecondaryUse_performed")] [HarmonyPrefix] public static bool PreventItemSecondaryUseInMenu(CallbackContext context) { if (ConfigSettings.disableEmotesForSelf.Value) { return true; } return !isMenuOpen; } [HarmonyPatch(typeof(PlayerControllerB), "ItemTertiaryUse_performed")] [HarmonyPrefix] public static bool PreventItemTertiaryUseInMenu(CallbackContext context) { if (ConfigSettings.disableEmotesForSelf.Value) { return true; } return !isMenuOpen; } [HarmonyPatch(typeof(PlayerControllerB), "Interact_performed")] [HarmonyPrefix] public static bool PreventInteractInMenu(CallbackContext context) { if (ConfigSettings.disableEmotesForSelf.Value) { return true; } return !isMenuOpen; } [HarmonyPatch(typeof(QuickMenuManager), "OpenQuickMenu")] [HarmonyPrefix] public static bool OnOpenQuickMenu() { if (!isMenuOpen) { return true; } CloseEmoteMenu(); return false; } [HarmonyPatch(typeof(QuickMenuManager), "CloseQuickMenu")] [HarmonyPostfix] public static void OnCloseQuickMenu() { if (isMenuOpen) { CloseEmoteMenu(); } } [HarmonyPatch(typeof(PlayerControllerB), "KillPlayer")] [HarmonyPostfix] public static void OnLocalPlayerDeath(Vector3 bodyVelocity, PlayerControllerB __instance) { if (isMenuOpen && (Object)(object)__instance == (Object)(object)localPlayerController && __instance.isPlayerDead) { CloseEmoteMenu(); } } } public class EmoteUIElement { public GameObject uiGameObject; public int id; public Image backgroundImage; public TextMeshPro textContainer; public Color baseColor; public UnlockableEmote emote; public void OnHover(bool hovered = true) { //IL_0002: 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_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) Color color = baseColor * (hovered ? 1f : 0.5f); color.a = (hovered ? EmoteMenuManager.hoveredAlpha : EmoteMenuManager.unhoveredAlpha); ((Graphic)backgroundImage).color = color; } } public class EmoteLoadoutUIElement : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler { public static int uiCount; public int id; public string loadoutName; public Image backgroundImage; public TextMeshPro textContainer; private void Awake() { id = uiCount++; backgroundImage = ((Component)this).GetComponentInChildren<Image>(); textContainer = ((Component)this).GetComponentInChildren<TextMeshPro>(); ((TMP_Text)textContainer).text = loadoutName; } private void Start() { } public void OnHover(bool hovered = true) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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) Color color = ((EmoteMenuManager.currentLoadoutIndex == id) ? EmoteMenuManager.selectedLoadoutUIColor : EmoteMenuManager.defaultUIColor) * (hovered ? 1f : 0.5f); color.a = (hovered ? EmoteMenuManager.hoveredAlpha : EmoteMenuManager.unhoveredAlpha); ((Graphic)backgroundImage).color = color; } public void OnPointerEnter(PointerEventData eventData) { EmoteMenuManager.OnHoveredNewLoadoutElement(id); OnHover(); } public void OnPointerExit(PointerEventData eventData) { EmoteMenuManager.OnHoveredNewLoadoutElement(-1); OnHover(hovered: false); } } public class EmoteLoadoutUIContainer : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler { public static bool hovered; public void OnPointerEnter(PointerEventData eventData) { hovered = true; } public void OnPointerExit(PointerEventData eventData) { hovered = false; } } public class PlayerData { public PlayerControllerB playerController; public UnlockableEmote performingEmote; public bool isLocalPlayer => (Object)(object)playerController == (Object)(object)StartOfRound.Instance?.localPlayerController; public string name => ((Object)playerController).name; public ulong clientId => playerController.actualClientId; public ulong playerId => playerController.playerClientId; public ulong steamId => playerController.playerSteamId; public string username => playerController.playerUsername; public Animator animator => playerController.playerBodyAnimator; public AnimatorOverrideController animatorController { get { RuntimeAnimatorController runtimeAnimatorController = animator.runtimeAnimatorController; return (AnimatorOverrideController)(object)((runtimeAnimatorController is AnimatorOverrideController) ? runtimeAnimatorController : null); } set { animator.runtimeAnimatorController = (RuntimeAnimatorController)(object)value; } } public bool animatorControllerIsOverride => (Object)(object)animator.runtimeAnimatorController != (Object)null && animator.runtimeAnimatorController is AnimatorOverrideController; public RigBuilder rigBuilder => ((Component)playerController).GetComponentInChildren<RigBuilder>(); public int currentEmoteNumber { get { return animator.GetInteger("emoteNumber"); } set { animator.SetInteger("emoteNumber", value); } } public bool isPerformingEmote => performingEmote != null; public float normalizedTimeAnimation { get { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) AnimatorStateInfo currentAnimatorStateInfo = animator.GetCurrentAnimatorStateInfo(1); return ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime; } } public void ConvertAnimatorControllerToOverride() { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown if ((Object)(object)animator != (Object)null && !(animator.runtimeAnimatorController is AnimatorOverrideController)) { Plugin.LogWarning("Converting animator controller to override for player: " + ((Object)playerController).name); animator.runtimeAnimatorController = (RuntimeAnimatorController)new AnimatorOverrideController(animator.runtimeAnimatorController); } } public void EnableRigBuilder(bool enable) { Plugin.Log((enable ? "Enabling " : "Disabling ") + "rigbuilder for player with id: " + playerController.actualClientId); if (enable) { ((MonoBehaviour)playerController).StartCoroutine(EnableRigBuilder()); } else { ((Behaviour)rigBuilder).enabled = false; } IEnumerator EnableRigBuilder() { TryGetCurrentAnimationClip(out var currentAnimationClip); int currentEmoteNumber = playerController.playerBodyAnimator.GetInteger("emoteNumber"); AnimatorStateInfo currentAnimatorStateInfo = playerController.playerBodyAnimator.GetCurrentAnimatorStateInfo(1); int prevState = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).shortNameHash; currentAnimatorStateInfo = playerController.playerBodyAnimator.GetCurrentAnimatorStateInfo(1); float normalizedTime = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime; SetCurrentAnimationClip(Plugin.idleClip); playerController.playerBodyAnimator.SetInteger("emoteNumber", 1); playerController.playerBodyAnimator.Play("Dance1", 1, 0f); yield return (object)new WaitForEndOfFrame(); SetCurrentAnimationClip(currentAnimationClip); playerController.playerBodyAnimator.SetInteger("emoteNumber", currentEmoteNumber); currentAnimatorStateInfo = playerController.playerBodyAnimator.GetCurrentAnimatorStateInfo(1); int currentState = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).shortNameHash; if (currentState != prevState) { playerController.playerBodyAnimator.CrossFadeInFixedTime(prevState, 0.1f, 1); } else { playerController.playerBodyAnimator.Play(prevState, 1, normalizedTime); } ((Behaviour)rigBuilder).enabled = enable; } } public bool TryGetCurrentAnimationClip(out AnimationClip animationClip, string stateName = "Dance1") { animationClip = null; try { if (!(animator.runtimeAnimatorController is AnimatorOverrideController)) { ConvertAnimatorControllerToOverride(); } animationClip = animatorController[stateName]; } catch { } return (Object)(object)animationClip != (Object)null; } public void SetCurrentAnimationClip(AnimationClip clip, string stateName = "Dance1") { if (!(animator.runtimeAnimatorController is AnimatorOverrideController)) { ConvertAnimatorControllerToOverride(); } animatorController[stateName] = clip; } public bool IsEmoteLoaded() { UnlockableEmote emote; return TryGetLoadedEmote(out emote); } public bool TryGetLoadedEmote(out UnlockableEmote emote) { emote = null; if (TryGetCurrentAnimationClip(out var animationClip)) { string key = ((Object)animationClip).name.Replace("_loop", "").Replace("_start", "").Replace("_pose", ""); if (StartOfRoundPatcher.allUnlockableEmotesDict.TryGetValue(key, out var value)) { emote = value; } } return emote != null; } public void PlayEmoteAtTime(UnlockableEmote emote, AnimationClip overrideClip = null, float normalizedTime = 0f, bool playEmoteEndOfFrame = false) { if (playEmoteEndOfFrame) { ((MonoBehaviour)playerController).StartCoroutine(PlayEmoteEndOfFrame()); return; } AnimationClip val = (((Object)(object)overrideClip != (Object)null) ? overrideClip : emote.animationClip); SetCurrentAnimationClip(val); playerController.playerBodyAnimator.Play("Dance1", 1, normalizedTime); if ((Object)(object)val == (Object)(object)emote.animationClip && (Object)(object)emote.transitionsToClip != (Object)null) { ((MonoBehaviour)playerController).StartCoroutine(TransitionToLoopEmote(emote)); } else if (!((Motion)val).isLooping && !emote.isPose) { ((MonoBehaviour)playerController).StartCoroutine(StopEmoteAfterFinished(emote)); } if (isLocalPlayer) { ThirdPersonEmoteController.OnStartCustomEmoteLocal(); if ((Object)(object)playerController.localItemHolder == (Object)(object)playerController.currentlyHeldObjectServer?.parentObject) { playerController.currentlyHeldObjectServer.parentObject = playerController.serverItemHolder; } } IEnumerator PlayEmoteEndOfFrame() { yield return (object)new WaitForEndOfFrame(); PlayEmoteAtTime(emote, overrideClip, normalizedTime); } } private IEnumerator TransitionToLoopEmote(UnlockableEmote emote) { yield return (object)new WaitForSeconds(emote.animationClip.length); if (TryGetCurrentAnimationClip(out var currentAnimationClip) && (Object)(object)currentAnimationClip == (Object)(object)emote.animationClip && (normalizedTimeAnimation >= 0.9f || !isLocalPlayer)) { SetCurrentAnimationClip(((Object)(object)emote.transitionsToClip != (Object)null) ? emote.transitionsToClip : PlayerPatcher.defaultDance1Clip); playerController.playerBodyAnimator.Play("Dance1", 1, 0f); } } private IEnumerator StopEmoteAfterFinished(UnlockableEmote emote) { yield return (object)new WaitForSeconds(emote.animationClip.length); if (TryGetCurrentAnimationClip(out var currentAnimationClip) && (Object)(object)currentAnimationClip == (Object)(object)emote.animationClip && (normalizedTimeAnimation >= 0.9f || !isLocalPlayer)) { playerController.performingEmote = false; if (((NetworkBehaviour)playerController).IsOwner) { playerController.StopPerformingEmoteServerRpc(); } } } public PlayerData(PlayerControllerB playerController) { this.playerController = playerController; } } public class UnlockableEmote { public int emoteId; public string emoteName; public string randomEmotePoolName = ""; public string displayName = ""; public bool purchasable = true; public AnimationClip animationClip; public AnimationClip transitionsToClip = null; public List<UnlockableEmote> randomEmotePool; public bool complementary = false; public bool isPose = false; public bool canSyncEmote = false; public bool favorite = false; public int rarity = 0; public static string[] rarityColorCodes = new string[4] { ConfigSettings.emoteNameColorTier0.Value, ConfigSettings.emoteNameColorTier1.Value, ConfigSettings.emoteNameColorTier2.Value, ConfigSettings.emoteNameColorTier3.Value }; public string displayNameColorCoded => $"<color={nameColor}>{displayName}</color>"; public bool loopable => ((Motion)animationClip).isLooping || ((Object)(object)transitionsToClip != (Object)null && ((Motion)transitionsToClip).isLooping); public string rarityText { get { if (rarity == 0) { return "Common"; } if (rarity == 1) { return "Rare"; } if (rarity == 2) { return "Epic"; } if (rarity == 3) { return "Legendary"; } return "Invalid"; } } public int price { get { int num = -1; if (complementary) { num = 0; } else if (rarity == 0) { num = ConfigSync.instance.syncBasePriceEmoteTier0; } else if (rarity == 1) { num = ConfigSync.instance.syncBasePriceEmoteTier1; } else if (rarity == 2) { num = ConfigSync.instance.syncBasePriceEmoteTier2; } else if (rarity == 3) { num = ConfigSync.instance.syncBasePriceEmoteTier3; } return (int)Mathf.Max((float)num * ConfigSync.instance.syncPriceMultiplierEmotesStore, 0f); } } public string nameColor => rarityColorCodes[rarity]; public bool ClipIsInEmote(AnimationClip clip) { return (Object)(object)clip != (Object)null && ((Object)(object)clip == (Object)(object)animationClip || (Object)(object)clip == (Object)(object)transitionsToClip); } } [BepInPlugin("FlipMods.TooManyEmotes", "TooManyEmotes", "1.8.6")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { private Harmony _harmony; public static Plugin instance; private static ManualLogSource logger; public static List<AnimationClip> customAnimationClips; public static HashSet<AnimationClip> customAnimationClipsHash; public static Dictionary<string, AnimationClip> customAnimationClipsLoopDict = new Dictionary<string, AnimationClip>(); public static List<AnimationClip> complementaryAnimationClips; public static List<AnimationClip> animationClipsTier0; public static List<AnimationClip> animationClipsTier1; public static List<AnimationClip> animationClipsTier2; public static List<AnimationClip> animationClipsTier3; public static AnimationClip idleClip; public static GameObject radialMenuPrefab; public static RuntimeAnimatorController previewAnimatorController; public static Dictionary<string, AudioClip> musicClips; private void Awake() { //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Expected O, but got Unknown instance = this; CreateCustomLogger(); ConfigSettings.BindConfigSettings(); Keybinds.InitKeybinds(); customAnimationClips = new List<AnimationClip>(); customAnimationClipsLoopDict = new Dictionary<string, AnimationClip>(); complementaryAnimationClips = new List<AnimationClip>(LoadEmoteAssetBundle("Assets/emotes_complementary")); animationClipsTier0 = new List<AnimationClip>(LoadEmoteAssetBundle("Assets/emotes_0")); animationClipsTier1 = new List<AnimationClip>(LoadEmoteAssetBundle("Assets/emotes_1")); animationClipsTier2 = new List<AnimationClip>(LoadEmoteAssetBundle("Assets/emotes_2")); animationClipsTier3 = new List<AnimationClip>(LoadEmoteAssetBundle("Assets/emotes_3")); AnimationClip[] array = LoadEmoteAssetBundle("Assets/emotes_misc"); if (array != null && array.Length >= 1) { AnimationClip[] array2 = array; foreach (AnimationClip val in array2) { if (((Object)val).name.Contains("idle")) { idleClip = val; } } } customAnimationClips.AddRange(complementaryAnimationClips); customAnimationClips.AddRange(animationClipsTier0); customAnimationClips.AddRange(animationClipsTier1); customAnimationClips.AddRange(animationClipsTier2); customAnimationClips.AddRange(animationClipsTier3); foreach (AnimationClip customAnimationClip in customAnimationClips) { if (((Object)customAnimationClip).name.StartsWith("fn_")) { ((Object)customAnimationClip).name = ((Object)customAnimationClip).name.Replace("fn_", ""); } if (((Object)customAnimationClip).name.EndsWith("_loop")) { customAnimationClipsLoopDict.Add(((Object)customAnimationClip).name, customAnimationClip); } } foreach (AnimationClip value in customAnimationClipsLoopDict.Values) { customAnimationClips.Remove(value); } customAnimationClipsHash = new HashSet<AnimationClip>(customAnimationClips); customAnimationClipsHash.UnionWith(customAnimationClipsLoopDict.Values); LoadRadialMenuAsset(); _harmony = new Harmony("TooManyEmotes"); PatchAll(); Log("TooManyEmotes loaded"); } private static AnimationClip[] LoadEmoteAssetBundle(string assetBundleName) { try { string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)instance).Info.Location), assetBundleName); AssetBundle val = AssetBundle.LoadFromFile(text); AnimationClip[] array = val.LoadAllAssets<AnimationClip>(); Log($"Successfully loaded {array.Length} animation clips from asset bundle: {assetBundleName}"); return array; } catch { LogError("Failed to load emotes asset bundle: " + assetBundleName + "."); return (AnimationClip[])(object)new AnimationClip[0]; } } public static void LoadRadialMenuAsset() { try { string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)instance).Info.Location), "Assets/radial_menu"); AssetBundle val = AssetBundle.LoadFromFile(text); radialMenuPrefab = val.LoadAsset<GameObject>("RadialMenu"); previewAnimatorController = val.LoadAsset<RuntimeAnimatorController>("PreviewAnimatorController"); Log("Successfully loaded radial menu asset."); } catch { LogError("Failed to load radial menu asset."); } } private void PatchAll() { IEnumerable<Type> enumerable; try { enumerable = Assembly.GetExecutingAssembly().GetTypes(); } catch (ReflectionTypeLoadException ex) { enumerable = ex.Types.Where((Type t) => t != null); } foreach (Type item in enumerable) { _harmony.PatchAll(item); } } private void CreateCustomLogger() { try { logger = Logger.CreateLogSource($"{((BaseUnityPlugin)this).Info.Metadata.Name}-{((BaseUnityPlugin)this).Info.Metadata.Version}"); } catch { logger = ((BaseUnityPlugin)this).Logger; } } public static void Log(string message) { logger.LogInfo((object)message); } public static void LogError(string message) { logger.LogError((object)message); } public static void LogWarning(string message) { logger.LogWarning((object)message); } public static bool IsModLoaded(string guid) { return Chainloader.PluginInfos.ContainsKey(guid); } } public static class PluginInfo { public const string PLUGIN_GUID = "FlipMods.TooManyEmotes"; public const string PLUGIN_NAME = "TooManyEmotes"; public const string PLUGIN_VERSION = "1.8.6"; } [HarmonyPatch] public static class UpdateKeybindDisplayNames { public static bool usingControllerPrevious; public static bool usingController => StartOfRound.Instance.localPlayerUsingController; [HarmonyPatch(typeof(HUDManager), "Update")] [HarmonyPostfix] public static void CheckForInputSourceUpdate() { if (usingController != usingControllerPrevious) { usingControllerPrevious = usingController; UpdateControlTipLines(); } } [HarmonyPatch(typeof(KepRemapPanel), "OnDisable")] [HarmonyPostfix] public static void OnCloseRemapPanel() { UpdateControlTipLines(); } public static void UpdateControlTipLines() { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) if (EmoteMenuManager.isMenuOpen) { EmoteMenuManager.UpdateControlTipLines(); } for (int i = 0; i < HUDManager.Instance.controlTipLines.Length; i++) { TextMeshProUGUI val = HUDManager.Instance.controlTipLines[i]; if ((Object)(object)val != (Object)null && ((Component)val).gameObject.activeSelf && ((Behaviour)val).enabled && ((TMP_Text)val).text.Contains("Emote Radial Menu")) { int num = (usingController ? 1 : 0); InputBinding val2 = Keybinds.OpenEmoteMenuAction.bindings[num]; string displayName = ConfigSettings.GetDisplayName(((InputBinding)(ref val2)).overridePath); if (displayName != "") { ((TMP_Text)HUDManager.Instance.controlTipLines[i]).text = $"[{displayName}]: Open Emote Radial Menu"; } break; } } ThirdPersonEmoteController.UpdateControlTip(); } } } namespace TooManyEmotes.Config { public static class ConfigSettings { public static ConfigEntry<bool> unlockEverything; public static ConfigEntry<bool> shareEverything; public static ConfigEntry<bool> syncUnsharedEmotes; public static ConfigEntry<bool> enableMovingWhileEmoting; public static ConfigEntry<bool> disableRaritySystem; public static ConfigEntry<int> basePriceEmoteRaritySystemDisabled; public static ConfigEntry<int> startingEmoteCredits; public static ConfigEntry<float> addEmoteCreditsMultiplier; public static ConfigEntry<bool> purchaseEmotesWithDefaultCurrency; public static ConfigEntry<float> priceMultiplierEmotesStore; public static ConfigEntry<int> basePriceEmoteTier0; public static ConfigEntry<int> basePriceEmoteTier1; public static ConfigEntry<int> basePriceEmoteTier2; public static ConfigEntry<int> basePriceEmoteTier3; public static ConfigEntry<int> numEmotesStoreRotation; public static ConfigEntry<float> rotationChanceEmoteTier0; public static ConfigEntry<float> rotationChanceEmoteTier1; public static ConfigEntry<float> rotationChanceEmoteTier2; public static ConfigEntry<float> rotationChanceEmoteTier3; public static ConfigEntry<bool> enableMaskedEnemiesEmoting; public static ConfigEntry<float> maskedEnemiesEmoteChanceOnEncounter; public static ConfigEntry<bool> maskedEnemiesAlwaysEmoteOnFirstEncounter; public static ConfigEntry<bool> enableSyncingEmotesWithMaskedEnemies; public static ConfigEntry<bool> overrideStopAndStareDuration; public static ConfigEntry<string> maskedEnemyEmoteRandomDelay; public static ConfigEntry<string> maskedEnemyEmoteRandomDuration; public static ConfigEntry<bool> disableEmotesForSelf; public static ConfigEntry<string> openEmoteMenuKeybind; public static ConfigEntry<string> rotateCharacterInEmoteKeybind; public static ConfigEntry<bool> toggleRotateCharacterInEmote; public static ConfigEntry<bool> toggleEmoteMenu; public static ConfigEntry<bool> reverseEmoteWheelScrollDirection; public static ConfigEntry<string> quickEmoteFavorite1Keybind; public static ConfigEntry<string> quickEmoteFavorite2Keybind; public static ConfigEntry<string> quickEmoteFavorite3Keybind; public static ConfigEntry<string> quickEmoteFavorite4Keybind; public static ConfigEntry<string> quickEmoteFavorite5Keybind; public static ConfigEntry<string> quickEmoteFavorite6Keybind; public static ConfigEntry<string> quickEmoteFavorite7Keybind; public static ConfigEntry<string> quickEmoteFavorite8Keybind; public static ConfigEntry<string> emoteNameColorTier0; public static ConfigEntry<string> emoteNameColorTier1; public static ConfigEntry<string> emoteNameColorTier2; public static ConfigEntry<string> emoteNameColorTier3; public static Dictionary<string, ConfigEntryBase> currentConfigEntries = new Dictionary<string, ConfigEntryBase>(); public static List<string> configSections = new List<string>(); public static void BindConfigSettings() { Plugin.Log("BindingConfigs"); unlockEverything = AddConfigEntry("Emote Settings", "I am a Party Pooper", defaultValue: false, "[Host only] If true, every emote will be unlocked in your emote wheel at the start of the game. Also, you're not really a party pooper."); shareEverything = AddConfigEntry("Emote Settings", "ShareEverything", defaultValue: true, "[Host only] This setting will be ignored if \"I am a Party Pooper\" is enabled. If this setting is set to false, emotes in the store will be different for each player. Unlocking emotes will only unlock for the player that purchased the emote. Each player will have their own emote credits. The amount of emote credits that each player will receive will NOT be reduced."); syncUnsharedEmotes = AddConfigEntry("Emote Settings", "CanSyncUnsharedEmotes", defaultValue: true, "[Host only] Only applies if ShareEverything is false. If set to true, players will be able to sync emotes with other players, even if they do not have the emote being performed unlocked."); enableMovingWhileEmoting = AddConfigEntry("Emote Settings", "CanMoveWhileEmoting", defaultValue: false, "[Host only] If set to true, rotating while emoting will be automatic. To cancel an emote, you will press the vanilla menu button."); disableRaritySystem = AddConfigEntry("Emote Settings", "DisableRaritySystem", defaultValue: false, "[Host only] If true, every emote will have the same likelyhood of appearing in the emote store."); basePriceEmoteRaritySystemDisabled = AddConfigEntry("Emote Settings", "BasePriceEmote - Rarity System Disabled", 100, "[Host only] Base price of emotes if the rarity system is disabled."); startingEmoteCredits = AddConfigEntry("Emote Settings", "StartingEmoteCredits", 100, "[Host only] The number of emote credits you start each game with."); addEmoteCreditsMultiplier = AddConfigEntry("Emote Settings", "AddEmoteCreditsMultiplier", 0.4f, "[Host only] You gain emote credits based off this multiplier of normal group credits earned. Example: If set to the default, 0.25, and you earn 200 group credits, you will also gain 50 emote credits."); purchaseEmotesWithDefaultCurrency = AddConfigEntry("Emote Settings", "PurchaseEmotesWithDefaultCredits", defaultValue: true, "[Host only] Setting this to true will allow you to purchase emotes with normal group credits once you run out of emote credits. This setting will automatically be disabled if ShareEverything is false."); priceMultiplierEmotesStore = AddConfigEntry("Emote Settings", "PriceMultiplierEmotesStore", 1f, "[Host only] Price multiplier for emotes in the store. Only applies if UnlockEverythingAtStart is false."); basePriceEmoteTier0 = AddConfigEntry("Emote Settings", "PriceCommonEmote", 50, "[Host only] The base price of [common]emotes in the store."); basePriceEmoteTier1 = AddConfigEntry("Emote Settings", "PriceRareEmote", 100, "[Host only] The base price of [rare] emotes in the store."); basePriceEmoteTier2 = AddConfigEntry("Emote Settings", "PriceEpicEmote", 200, "[Host only] The base price of [epic] emotes in the store."); basePriceEmoteTier3 = AddConfigEntry("Emote Settings", "PriceLegendaryEmote", 300, "[Host only] The base price of [legendary] emotes in the store."); numEmotesStoreRotation = AddConfigEntry("Emote Settings", "EmotesInStoreRotation", 6, "[Host only] The number of emotes that will be available at a time in the store. Only applies if UnlockEverythingAtStart is false."); rotationChanceEmoteTier0 = AddConfigEntry("Emote Settings", "RotationWeightCommonEmote", 0.55f, "[Host only] The likelyhood of [common] emotes appearing (per slot) in the store rotation."); rotationChanceEmoteTier1 = AddConfigEntry("Emote Settings", "RotationWeightRareEmote", 0.35f, "[Host only] The likelyhood of [rare] emotes appearing (per slot) in the store rotation."); rotationChanceEmoteTier2 = AddConfigEntry("Emote Settings", "RotationWeightEpicEmote", 0.08f, "[Host only] The likelyhood of [epic] emotes appearing (per slot) in the store rotation."); rotationChanceEmoteTier3 = AddConfigEntry("Emote Settings", "RotationWeightLegendaryEmote", 0.02f, "[Host only] The likelyhood of [legendary] emotes appearing (per slot) in the store rotation."); enableMaskedEnemiesEmoting = AddConfigEntry("MaskedEnemyEmotes - Beta", "EnableMaskedEnemiesEmoting", defaultValue: true, "[Host only] Enabling this alone does not change the behaviour of the Masked Enemies, and shouldn't conflict with other mods."); maskedEnemiesEmoteChanceOnEncounter = AddConfigEntry("MaskedEnemyEmotes - Beta", "EmoteChanceOnEncounter", 0.25f, "[Host only] Chance per encounter with a Masked Enemy, for them to perform an emote. Use values between 0 and 1."); maskedEnemiesAlwaysEmoteOnFirstEncounter = AddConfigEntry("MaskedEnemyEmotes - Beta", "AlwaysEmoteOnFirstEncounter", defaultValue: true, "[Host only] This will force the first encounter (for each player) with a Masked Enemy to trigger an emote, regardless of EmoteChanceOnEncounter."); enableSyncingEmotesWithMaskedEnemies = AddConfigEntry("MaskedEnemyEmotes - Beta", "EnableSyncingEmotesWithMaskedEnemies", defaultValue: true, "[Client-side] Enabling this will allow you to sync emotes with Masked Enemies. This config is mainly here to disable in case of strange issues."); maskedEnemyEmoteRandomDelay = AddConfigEntry("MaskedEnemyEmotes - Beta", "RandomEmoteDelay", "1.5,2.0", "[Host only] Random range at which Masked Enemies will delay before performing an emote. These values could be raised a bit if OverrideStopAndStareDuration is enabled, otherwise, you may run into emotes ending quickly."); overrideStopAndStareDuration = AddConfigEntry("MaskedEnemyEmotes - Beta", "OverrideStopAndStareDuration", defaultValue: true, "[Host only] Enabling this will allow this mod to extend the stop and stare duration for longer emotes. If disabled, emotes may end very quickly. Disable this setting if you run into mod conflicts."); maskedEnemyEmoteRandomDuration = AddConfigEntry("MaskedEnemyEmotes - Beta", "RandomEmoteDuration", "2.0,4.0", "[Host only] Random range on how long Masked Enemies will emote for. This will extend the Masked Enemies' stop and stare duration by this amount. Only applies if OverrideStopAndStareDuration is true."); disableEmotesForSelf = AddConfigEntry("Emote Radial Menu", "DisableEmotingForSelf", defaultValue: false, "Disabling this will not convert your player's animator controller to an AnimatorOverrideController, and you will not be able to perform custom emotes. Disable this in case of specific mod conflicts. You will still be able to see other players emoting."); openEmoteMenuKeybind = AddConfigEntry("Emote Radial Menu", "OpenEmoteMenuKeybind", "<Keyboard>/backquote", "NOTE: This setting will be ignored if InputUtils is installed and enabled. (I recommend running InputUtils to edit keybinds in the in-game settings)"); rotateCharacterInEmoteKeybind = AddConfigEntry("Emote Radial Menu", "RotateCharacterInEmoteKeybind", "<Keyboard>/leftAlt", "Keybind to hold to rotate character while performing a custom emote. NOTE: This setting will be ignored if InputUtils is installed and enabled. (I recommend running InputUtils to edit keybinds in the in-game settings)"); toggleRotateCharacterInEmote = AddConfigEntry("Emote Radial Menu", "ToggleRotateCharacterInEmote", defaultValue: false, "If true, rotating character while emoting will be toggled, instead of rotating while holding the hotkey."); toggleEmoteMenu = AddConfigEntry("Emote Radial Menu", "ToggleEmoteMenu", defaultValue: false, "If set to false, the emote menu will open upon pressing the related keybind, and close upon releasing, and will play the currently hovered emote."); reverseEmoteWheelScrollDirection = AddConfigEntry("Emote Radial Menu", "ReverseEmoteWheelScrollDirection", defaultValue: false, "Reverses the page swapping direction in your emote when scrolling."); emoteNameColorTier0 = AddConfigEntry("Accessibility", "CommonEmoteNameColor", "#00FF00", "The color of the [common] emote name in the terminal."); emoteNameColorTier1 = AddConfigEntry("Accessibility", "RareEmoteNameColor", "#2828FF", "The color of the [rare] emote name in the terminal."); emoteNameColorTier2 = AddConfigEntry("Accessibility", "EpicEmoteNameColor", "#AA00EE", "The color of the [epic] emote name in the terminal."); emoteNameColorTier3 = AddConfigEntry("Accessibility", "LegendaryEmoteNameColor", "#FF2222", "The color of the [legendary] emote name in the terminal."); float value = rotationChanceEmoteTier0.Value; value += rotationChanceEmoteTier1.Value; value += rotationChanceEmoteTier2.Value; value += rotationChanceEmoteTier3.Value; if (value != 1f && value != 0f) { ConfigEntry<float> obj = rotationChanceEmoteTier0; obj.Value /= value; ConfigEntry<float> obj2 = rotationChanceEmoteTier1; obj2.Value /= value; ConfigEntry<float> obj3 = rotationChanceEmoteTier2; obj3.Value /= value; ConfigEntry<float> obj4 = rotationChanceEmoteTier3; obj4.Value /= value; ((BaseUnityPlugin)Plugin.instance).Config.Save(); } TryRemoveOldConfigSettings(); ConfigSync.BuildDefaultConfigSync(); } public static ConfigEntry<T> AddConfigEntry<T>(string section, string name, T defaultValue, string description) { ConfigEntry<T> val = ((BaseUnityPlugin)Plugin.instance).Config.Bind<T>(section, name, defaultValue, description); currentConfigEntries.Add(((ConfigEntryBase)val).Definition.Key, (ConfigEntryBase)(object)val); return val; } public static string GetDisplayName(string key) { try { if (key.Length <= 1) { return key; } int num = key.IndexOf(">/"); key = ((num >= 0) ? key.Substring(num + 2) : key); string text = key.ToLower(); if (text.Contains("not-bound")) { return ""; } text = text.Replace("leftalt", "Alt"); text = text.Replace("rightalt", "Alt"); text = text.Replace("leftctrl", "Ctrl"); text = text.Replace("rightctrl", "Ctrl"); text = text.Replace("leftshift", "Shift"); text = text.Replace("rightshift", "Shift"); text = text.Replace("leftbutton", "LMB"); text = text.Replace("rightbutton", "RMB"); text = text.Replace("middlebutton", "MMB"); text = text.Replace("lefttrigger", "LT"); text = text.Replace("righttrigger", "RT"); text = text.Replace("leftshoulder", "LB"); text = text.Replace("rightshoulder", "RB"); text = text.Replace("leftstickpress", "LS"); text = text.Replace("rightstickpress", "RS"); text = text.Replace("dpad/", "DPad-"); text = text.Replace("backquote", "`"); try { text = char.ToUpper(text[0]) + text.Substring(1); } catch { } return text; } catch { return ""; } } public static void TryRemoveOldConfigSettings() { HashSet<string> hashSet = new HashSet<string>(); HashSet<string> hashSet2 = new HashSet<string>(); foreach (ConfigEntryBase value in currentConfigEntries.Values) { hashSet.Add(value.Definition.Section); hashSet2.Add(value.Definition.Key); } try { Plugin.Log("Cleaning old config entries"); ConfigFile config = ((BaseUnityPlugin)Plugin.instance).Config; string configFilePath = config.ConfigFilePath; if (!File.Exists(configFilePath)) { return; } string text = File.ReadAllText(configFilePath); string[] array = File.ReadAllLines(configFilePath); string text2 = ""; for (int i = 0; i < array.Length; i++) { array[i] = array[i].Replace("\n", ""); if (array[i].Length <= 0) { continue; } if (array[i].StartsWith("[")) { if (text2 != "" && !hashSet.Contains(text2)) { text2 = "[" + text2 + "]"; int num = text.IndexOf(text2); int num2 = text.IndexOf(array[i]); text = text.Remove(num, num2 - num); } text2 = array[i].Replace("[", "").Replace("]", "").Trim(); } else { if (!(text2 != "")) { continue; } if (i <= array.Length - 4 && array[i].StartsWith("##")) { int j; for (j = 1; i + j < array.Length && array[i + j].Length > 3; j++) { } if (hashSet.Contains(text2)) { int num3 = array[i + j - 1].IndexOf("="); string item = array[i + j - 1].Substring(0, num3 - 1); if (!hashSet2.Contains(item)) { int num4 = text.IndexOf(array[i]); int num5 = text.IndexOf(array[i + j - 1]) + array[i + j - 1].Length; text = text.Remove(num4, num5 - num4); } } i += j - 1; } else if (array[i].Length > 3) { text = text.Replace(array[i], ""); } } } if (!hashSet.Contains(text2)) { text2 = "[" + text2 + "]"; int num6 = text.IndexOf(text2); text = text.Remove(num6, text.Length - num6); } while (text.Contains("\n\n\n")) { text = text.Replace("\n\n\n", "\n\n"); } File.WriteAllText(configFilePath, text); config.Reload(); } catch { } } } } namespace TooManyEmotes.Input { internal class InputUtilsCompat { internal static InputActionAsset Asset => IngameKeybinds.GetAsset(); internal static bool Enabled => Plugin.IsModLoaded("com.rune580.LethalCompanyInputUtils"); public static InputAction OpenEmoteMenuHotkey => IngameKeybinds.Instance.OpenEmoteMenuHotkey; public static InputAction RotateCharacterEmoteHotkey => IngameKeybinds.Instance.RotateCharacterEmoteHotkey; public static InputAction FavoriteEmoteHotkey => IngameKeybinds.Instance.FavoriteEmoteHotkey; public static InputAction PrevEmotePageHotkey => IngameKeybinds.Instance.PrevEmotePageHotkey; public static InputAction NextEmotePageHotkey => IngameKeybinds.Instance.NextEmotePageHotkey; public static InputAction NextEmoteLoadoutUpHotkey => IngameKeybinds.Instance.NextEmoteLoadoutUpHotkey; public static InputAction NextEmoteLoadoutDownHotkey => IngameKeybinds.Instance.NextEmoteLoadoutDownHotkey; public static InputAction ForceReloadPlayerModelHotkey => IngameKeybinds.Instance.ForceReloadPlayerModelHotkey; } internal class IngameKeybinds : LcInputActions { internal static IngameKeybinds Instance = new IngameKeybinds(); [InputAction("<Keyboard>/backquote", GamepadPath = "<Gamepad>/leftStickPress", Name = "Open Emote Menu")] public InputAction OpenEmoteMenuHotkey { get; set; } [InputAction("<Keyboard>/leftAlt", GamepadPath = "", Name = "Rotate Character in Emote")] public InputAction RotateCharacterEmoteHotkey { get; set; } [InputAction("<Mouse>/middleButton", GamepadPath = "<Gamepad>/rightStickPress", Name = "Favorite/Unfavorite Emote")] public InputAction FavoriteEmoteHotkey { get; set; } [InputAction("", GamepadPath = "<Gamepad>/dpad/left", Name = "Prev Emote Page")] public InputAction PrevEmotePageHotkey { get; set; } [InputAction("", GamepadPath = "<Gamepad>/dpad/right", Name = "Next Emote Page")] public InputAction NextEmotePageHotkey { get; set; } [InputAction("", GamepadPath = "<Gamepad>/dpad/up", Name = "Swap Emote Loadout Up")] public InputAction NextEmoteLoadoutUpHotkey { get; set; } [InputAction("", GamepadPath = "<Gamepad>/dpad/down", Name = "Swap Emote Loadout Down")] public InputAction NextEmoteLoadoutDownHotkey { get; set; } [InputAction("", GamepadPath = "", Name = "Force Reload Local Player Model")] public InputAction ForceReloadPlayerModelHotkey { get; set; } internal static InputActionAsset GetAsset() { return ((LcInputActions)Instance).Asset; } } [HarmonyPatch] public static class Keybinds { public static InputActionAsset Asset; public static InputActionMap ActionMap; public static InputAction OpenEmoteMenuAction; public static InputAction PerformSelectedEmoteAction; public static InputAction RotatePlayerEmoteAction; public static InputAction FavoriteEmoteAction; public static InputAction ThumbStickAction; public static InputAction PrevEmotePageAction; public static InputAction NextEmotePageAction; public static InputAction NextEmoteLoadoutUpAction; public static InputAction NextEmoteLoadoutDownAction; public static InputAction ForceReloadPlayerModelAction; public static InputAction RawScrollAction; public static bool holdingRotatePlayerModifier; public static bool toggledRotating; public static PlayerControllerB localPlayerController => StartOfRound.Instance?.localPlayerController; public static void InitKeybinds() { //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Expected O, but got Unknown //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Expected O, but got Unknown //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Expected O, but got Unknown //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Expected O, but got Unknown //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Expected O, but got Unknown //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Expected O, but got Unknown Plugin.Log("Initializing custom emote hotkeys."); if (InputUtilsCompat.Enabled) { Asset = InputUtilsCompat.Asset; ActionMap = Asset.actionMaps[0]; OpenEmoteMenuAction = InputUtilsCompat.OpenEmoteMenuHotkey; RotatePlayerEmoteAction = InputUtilsCompat.RotateCharacterEmoteHotkey; FavoriteEmoteAction = InputUtilsCompat.FavoriteEmoteHotkey; PrevEmotePageAction = InputUtilsCompat.PrevEmotePageHotkey; NextEmotePageAction = InputUtilsCompat.NextEmotePageHotkey; NextEmoteLoadoutUpAction = InputUtilsCompat.NextEmoteLoadoutUpHotkey; NextEmoteLoadoutDownAction = InputUtilsCompat.NextEmoteLoadoutDownHotkey; ForceReloadPlayerModelAction = InputUtilsCompat.ForceReloadPlayerModelHotkey; ThumbStickAction = new InputAction("TooManyEmotes.ThumbStick", (InputActionType)0, "<Gamepad>/rightStick", (string)null, (string)null, (string)null); PerformSelectedEmoteAction = new InputAction("TooManyEmotes.PerformSelectedEmote", (InputActionType)0, "<Mouse>/leftButton", "Press", (string)null, (string)null); RawScrollAction = new InputAction("TooManyEmotes.ScrollEmoteMenu", (InputActionType)0, "<Mouse>/scroll", (string)null, (string)null, (string)null); } else { Asset = ScriptableObject.CreateInstance<InputActionAsset>(); ActionMap = new InputActionMap("TooManyEmotes"); InputActionSetupExtensions.AddActionMap(Asset, ActionMap); OpenEmoteMenuAction = InputActionSetupExtensions.AddAction(ActionMap, "TooManyEmotes.OpenEmoteMenu", (InputActionType)0, ConfigSettings.openEmoteMenuKeybind.Value, "Press", (string)null, (string)null, (string)null); InputActionSetupExtensions.AddBinding(OpenEmoteMenuAction, "<Gamepad>/leftStickPress", (string)null, (string)null, (string)null); RotatePlayerEmoteAction = InputActionSetupExtensions.AddAction(ActionMap, "TooManyEmotes.RotatePlayerEmote", (InputActionType)0, ConfigSettings.rotateCharacterInEmoteKeybind.Value, "Press", (string)null, (string)null, (string)null); InputActionSetupExtensions.AddBinding(RotatePlayerEmoteAction, "<Gamepad>/", (string)null, (string)null, (string)null); FavoriteEmoteAction = InputActionSetupExtensions.AddAction(ActionMap, "TooManyEmotes.FavoriteEmote", (InputActionType)0, "<Mouse>/middleButton", "Press", (string)null, (string)null, (string)null); InputActionSetupExtensions.AddBinding(FavoriteEmoteAction, "<Gamepad>/rightStickPress", (string)null, (string)null, (string)null); PrevEmotePageAction = InputActionSetupExtensions.AddAction(ActionMap, "TooManyEmotes.PrevEmotePage", (InputActionType)0, "<Keyboard>/", "Press", (string)null, (string)null, (string)null); InputActionSetupExtensions.AddBinding(PrevEmotePageAction, "<Gamepad>/dpad/left", (string)null, (string)null, (string)null); NextEmotePageAction = InputActionSetupExtensions.AddAction(ActionMap, "TooManyEmotes.NextEmotePage", (InputActionType)0, "<Keyboard>/", "Press", (string)null, (string)null, (string)null); InputActionSetupExtensions.AddBinding(NextEmotePageAction, "<Gamepad>/dpad/right", (string)null, (string)null, (string)null); NextEmoteLoadoutUpAction = InputActionSetupExtensions.AddAction(ActionMap, "TooManyEmotes.EmoteLoadoutUp", (InputActionType)0, "<Keyboard>/", "Press", (string)null, (string)null, (string)null); InputActionSetupExtensions.AddBinding(NextEmoteLoadoutUpAction, "<Gamepad>/dpad/up", (string)null, (string)null, (string)null); NextEmoteLoadoutDownAction = InputActionSetupExtensions.AddAction(ActionMap, "TooManyEmotes.EmoteLoadoutDown", (InputActionType)0, "<Keyboard>/", "Press", (string)null, (string)null, (string)null); InputActionSetupExtensions.AddBinding(NextEmoteLoadoutDownAction, "<Gamepad>/dpad/down", (string)null, (string)null, (string)null); ForceReloadPlayerModelAction = InputActionSetupExtensions.AddAction(ActionMap, "TooManyEmotes.ForceReloadPlayerModel", (InputActionType)0, "<Keyboard>/", "Press", (string)null, (string)null, (string)null); InputActionSetupExtensions.AddBinding(ForceReloadPlayerModelAction, "<Gamepad>/", (string)null, (string)null, (string)null); ThumbStickAction = new InputAction("TooManyEmotes.ThumbStick", (InputActionType)0, "<Gamepad>/rightStick", (string)null, (string)null, (string)null); PerformSelectedEmoteAction = new InputAction("TooManyEmotes.PerformSelectedEmote", (InputActionType)0, "<Mouse>/leftButton", "Press", (string)null, (string)null); RawScrollAction = new InputAction("TooManyEmotes.ScrollEmoteMenu", (InputActionType)0, "<Mouse>/scroll", (string)null, (string)null, (string)null); } } [HarmonyPatch(typeof(StartOfRound), "OnEnable")] [HarmonyPostfix] public static void OnEnable() { Asset.Enable(); OpenEmoteMenuAction.performed += OnPressOpenEmoteMenu; OpenEmoteMenuAction.canceled += OnPressOpenEmoteMenu; FavoriteEmoteAction.performed += OnFavoriteEmote; RotatePlayerEmoteAction.performed += OnUpdateRotatePlayerEmoteModifier; RotatePlayerEmoteAction.canceled += OnUpdateRotatePlayerEmoteModifier; PrevEmotePageAction.Enable(); NextEmotePageAction.Enable(); NextEmoteLoadoutUpAction.Enable(); NextEmoteLoadoutDownAction.Enable(); PrevEmotePageAction.performed += OnPrevEmotePage; NextEmotePageAction.performed += OnNextEmotePage; NextEmoteLoadoutUpAction.performed += OnEmoteLoadoutUp; NextEmoteLoadoutDownAction.performed += OnEmoteLoadoutDown; ForceReloadPlayerModelAction.performed += OnReloadPlayerModel; PerformSelectedEmoteAction.Enable(); PerformSelectedEmoteAction.performed += OnSelectEmoteUI; ThumbStickAction.Enable(); ThumbStickAction.performed += EmoteMenuManager.OnUpdateThumbStickAngle; } [HarmonyPatch(typeof(StartOfRound), "OnDisable")] [HarmonyPostfix] public static void OnDisable() { Asset.Disable(); OpenEmoteMenuAction.performed -= OnPressOpenEmoteMenu; OpenEmoteMenuAction.canceled -= OnPressOpenEmoteMenu; FavoriteEmoteAction.performed -= OnFavoriteEmote; RotatePlayerEmoteAction.performed -= OnUpdateRotatePlayerEmoteModifier; RotatePlayerEmoteAction.canceled -= OnUpdateRotatePlayerEmoteModifier; PrevEmotePageAction.Disable(); NextEmotePageAction.Disable(); NextEmoteLoadoutUpAction.Disable(); NextEmoteLoadoutDownAction.Disable(); PrevEmotePageAction.performed -= OnPrevEmotePage; NextEmotePageAction.performed -= OnNextEmotePage; NextEmoteLoadoutUpAction.performed -= OnEmoteLoadoutUp; NextEmoteLoadoutDownAction.performed -= OnEmoteLoadoutDown; ForceReloadPlayerModelAction.performed -= OnReloadPlayerModel; PerformSelectedEmoteAction.Disable(); PerformSelectedEmoteAction.performed -= OnSelectEmoteUI; ThumbStickAction.Disable(); ThumbStickAction.performed -= EmoteMenuManager.OnUpdateThumbStickAngle; } public static void OnPrevEmotePage(CallbackContext context) { if (!((Object)(object)localPlayerController == (Object)null) && !ConfigSettings.disableEmotesForSelf.Value && EmoteMenuManager.isMenuOpen && ((CallbackContext)(ref context)).performed) { EmoteMenuManager.SwapPrevPage(); } } public static void OnNextEmotePage(CallbackContext context) { if (!((Object)(object)localPlayerController == (Object)null) && !ConfigSettings.disableEmotesForSelf.Value && EmoteMenuManager.isMenuOpen && ((CallbackContext)(ref context)).performed) { EmoteMenuManager.SwapNextPage(); } } public static void OnEmoteLoadoutUp(CallbackContext context) { if (!((Object)(object)localPlayerController == (Object)null) && !ConfigSettings.disableEmotesForSelf.Value && EmoteMenuManager.isMenuOpen && ((CallbackContext)(ref context)).performed) { EmoteMenuManager.SetCurrentEmoteLoadout((EmoteMenuManager.currentLoadoutIndex != 0) ? (EmoteMenuManager.currentLoadoutIndex - 1) : (EmoteMenuManager.numLoadouts - 1)); } } public static void OnEmoteLoadoutDown(CallbackContext context) { if (!((Object)(object)localPlayerController == (Object)null) && !ConfigSettings.disableEmotesForSelf.Value && EmoteMenuManager.isMenuOpen && ((CallbackContext)(ref context)).performed) { EmoteMenuManager.SetCurrentEmoteLoadout((EmoteMenuManager.currentLoadoutIndex + 1) % EmoteMenuManager.numLoadouts); } } private static void OnPressOpenEmoteMenu(CallbackContext context) { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)localPlayerController == (Object)null || ConfigSettings.disableEmotesForSelf.Value) { return; } if (!EmoteMenuManager.isMenuOpen) { if (((CallbackContext)(ref context)).performed && EmoteMenuManager.CanOpenEmoteMenu()) { EmoteMenuManager.OpenEmoteMenu(); } } else if (ConfigSettings.toggleEmoteMenu.Value || StartOfRound.Instance.localPlayerUsingController) { if (((CallbackContext)(ref context)).performed) { EmoteMenuManager.CloseEmoteMenu(); } } else if (((CallbackContext)(ref context)).canceled) { if (EmoteMenuManager.hoveredEmoteIndex != -1) { PerformEmoteLocal(context); } EmoteMenuManager.CloseEmoteMenu(); } } private static void OnSelectEmoteUI(CallbackContext context) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)localPlayerController == (Object)null) && ((CallbackContext)(ref context)).performed && EmoteMenuManager.isMenuOpen) { if (EmoteMenuManager.hoveredLoadoutUIIndex != -1 && EmoteMenuManager.hoveredLoadoutUIIndex != EmoteMenuManager.currentLoadoutIndex) { EmoteMenuManager.SetCurrentEmoteLoadout(EmoteMenuManager.hoveredLoadoutUIIndex); } else if (EmoteMenuManager.hoveredEmoteIndex >= 0 && EmoteMenuManager.hoveredEmoteIndex < EmoteMenuManager.currentLoadoutEmotesList.Count) { PerformEmoteLocal(context); EmoteMenuManager.CloseEmoteMenu(); } } } public static void PerformEmoteLocal(CallbackContext context) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) if (EmoteMenuManager.hoveredEmoteIndex >= 0 && EmoteMenuManager.hoveredEmoteIndex < EmoteMenuManager.currentLoadoutEmotesList.Count && !ConfigSettings.disableEmotesForSelf.Value) { UnlockableEmote unlockableEmote = EmoteMenuManager.currentLoadoutEmotesList[EmoteMenuManager.hoveredEmoteIndex]; if (unlockableEmote != null) { localPlayerController.PerformEmote(context, -(unlockableEmote.emoteId + 1)); } } } public static void OnFavoriteEmote(CallbackContext context) { if (!((Object)(object)localPlayerController == (Object)null) && ((CallbackContext)(ref context)).performed && EmoteMenuManager.isMenuOpen && EmoteMenuManager.hoveredEmoteUIIndex != -1 && EmoteMenuManager.previewingEmote != null) { EmoteMenuManager.ToggleFavoriteHoveredEmote(); } } public static void OnQuickEmote(CallbackContext context, int quickEmoteNumber) { } public static void OnUpdateRotatePlayerEmoteModifier(CallbackContext context) { if ((Object)(object)localPlayerController == (Object)null || ConfigSettings.disableEmotesForSelf.Value || ConfigSync.instance.syncEnableMovingWhileEmoting) { return; } if (((CallbackContext)(ref context)).performed) { if (ConfigSettings.toggleRotateCharacterInEmote.Value) { toggledRotating = !toggledRotating; } else { holdingRotatePlayerModifier = true; } } else if (((CallbackContext)(ref context)).canceled && !ConfigSettings.toggleRotateCharacterInEmote.Value) { holdingRotatePlayerModifier = false; } } public static void OnReloadPlayerModel(CallbackContext context) { if (!((Object)(object)localPlayerController == (Object)null) && !ConfigSettings.disableEmotesForSelf.Value && ((CallbackContext)(ref context)).performed) { Plugin.Log("Reloading local player model."); ThirdPersonEmoteController.ReloadPlayerModel(localPlayerController); } } } } namespace TooManyEmotes.Networking { [Serializable] [HarmonyPatch] public class ConfigSync { public static bool isSynced; public static ConfigSync defaultConfig; public static ConfigSync instance; public bool syncUnlockEverything; public bool syncShareEverything; public bool syncSyncUnsharedEmotes; public bool syncEnableMovingWhileEmoting; public bool syncDisableRaritySystem; public int syncStartingEmoteCredits; public float syncAddEmoteCreditsMultiplier; public bool syncPurchaseEmotesWithDefaultCurrency; public float syncPriceMultiplierEmotesStore; public int syncBasePriceEmoteTier0; public int syncBasePriceEmoteTier1; public int syncBasePriceEmoteTier2; public int syncBasePriceEmoteTier3; public int syncNumEmotesStoreRotation; public float syncRotationChanceEmoteTier0; public float syncRotationChanceEmoteTier1; public float syncRotationChanceEmoteTier2; public float syncRotationChanceEmoteTier3; public bool syncEnableMaskedEnemiesEmoting; public float syncMaskedEnemiesEmoteChanceOnEncounter; public bool syncMaskedEnemiesAlwaysEmoteOnFirstEncounter; public bool syncOverrideStopAndStareDuration; public float syncMaskedEnemyEmoteRandomDelayMin; public float syncMaskedEnemyEmoteRandomDelayMax; public float syncMaskedEnemyEmoteRandomDurationMin; public float syncMaskedEnemyEmoteRandomDurationMax; public static Vector2 syncMaskedEnemyEmoteRandomDelay; public static Vector2 syncMaskedEnemyEmoteRandomDuration; public static HashSet<ulong> syncedClients; public ConfigSync() { //IL_0133: 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_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) syncUnlockEverything = ConfigSettings.unlockEverything.Value; syncShareEverything = ConfigSettings.shareEverything.Value; syncSyncUnsharedEmotes = ConfigSettings.syncUnsharedEmotes.Value; syncEnableMovingWhileEmoting = ConfigSettings.enableMovingWhileEmoting.Value; syncDisableRaritySystem = ConfigSettings.disableRaritySystem.Value; syncStartingEmoteCredits = ConfigSettings.startingEmoteCredits.Value; syncAddEmoteCreditsMultiplier = ConfigSettings.addEmoteCreditsMultiplier.Value; syncPurchaseEmotesWithDefaultCurrency = ConfigSettings.purchaseEmotesWithDefaultCurrency.Value; syncPriceMultiplierEmotesStore = ConfigSettings.priceMultiplierEmotesStore.Value; syncNumEmotesStoreRotation = ConfigSettings.numEmotesStoreRotation.Value; syncRotationChanceEmoteTier0 = ConfigSettings.rotationChanceEmoteTier0.Value; syncRotationChanceEmoteTier1 = ConfigSettings.rotationChanceEmoteTier1.Value; syncRotationChanceEmoteTier2 = ConfigSettings.rotationChanceEmoteTier2.Value; syncRotationChanceEmoteTier3 = ConfigSettings.rotationChanceEmoteTier3.Value; syncEnableMaskedEnemiesEmoting = ConfigSettings.enableMaskedEnemiesEmoting.Value; syncMaskedEnemiesEmoteChanceOnEncounter = ConfigSettings.maskedEnemiesEmoteChanceOnEncounter.Value; syncMaskedEnemiesAlwaysEmoteOnFirstEncounter = ConfigSettings.maskedEnemiesAlwaysEmoteOnFirstEncounter.Value; syncOverrideStopAndStareDuration = ConfigSettings.overrideStopAndStareDuration.Value; syncMaskedEnemyEmoteRandomDelay = ParseVector2FromString(ConfigSettings.maskedEnemyEmoteRandomDelay.Value); syncMaskedEnemyEmoteRandomDelayMin = syncMaskedEnemyEmoteRandomDelay.x; syncMaskedEnemyEmoteRandomDelayMax = syncMaskedEnemyEmoteRandomDelay.y; syncMaskedEnemyEmoteRandomDuration = ParseVector2FromString(ConfigSettings.maskedEnemyEmoteRandomDuration.Value); syncMaskedEnemyEmoteRandomDurationMin = syncMaskedEnemyEmoteRandomDuration.x; syncMaskedEnemyEmoteRandomDurationMax = syncMaskedEnemyEmoteRandomDuration.y; if (syncUnlockEverything) { syncShareEverything = true; } if (ConfigSettings.disableRaritySystem.Value) { syncBasePriceEmoteTier0 = ConfigSettings.basePriceEmoteRaritySystemDisabled.Value; syncBasePriceEmoteTier1 = ConfigSettings.basePriceEmoteRaritySystemDisabled.Value; syncBasePriceEmoteTier2 = ConfigSettings.basePriceEmoteRaritySystemDisabled.Value; syncBasePriceEmoteTier3 = ConfigSettings.basePriceEmoteRaritySystemDisabled.Value; } else { syncBasePriceEmoteTier0 = ConfigSettings.basePriceEmoteTier0.Value; syncBasePriceEmoteTier1 = ConfigSettings.basePriceEmoteTier1.Value; syncBasePriceEmoteTier2 = ConfigSettings.basePriceEmoteTier2.Value; syncBasePriceEmoteTier3 = ConfigSettings.basePriceEmoteTier3.Value; } } public Vector2 ParseVector2FromString(string str) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) Vector2 result = Vector2.zero; try { string[] array = str.Split(new char[1] { ',' }); if (float.TryParse(array[0].Trim(new char[1] { ' ' }), out var result2) && float.TryParse(array[1].Trim(new char[1] { ' ' }), out var result3)) { result = new Vector2(Mathf.Min(Mathf.Abs(result2), Mathf.Abs(result3)), Mathf.Max(Mathf.Abs(result2), Mathf.Abs(result3))); } return result; } catch { } return Vector2.zero; } public static void BuildDefaultConfigSync() { defaultConfig = new ConfigSync(); instance = new ConfigSync(); } [HarmonyPatch(typeof(StartOfRound), "Awake")] [HarmonyPostfix] public static void ResetValues() { isSynced = false; } [HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")] [HarmonyPostfix] public static void Init(PlayerControllerB __instance) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Expected O, but got Unknown if (isSynced) { return; } isSynced = NetworkManager.Singleton.IsServer; SyncManager.isSynced = false; SyncManager.requestedSync = false; if (NetworkManager.Singleton.IsServer) { syncedClients = new HashSet<ulong>(); NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("TooManyEmotes-OnRequestConfigSyncServerRpc", new HandleNamedMessageDelegate(OnRequestConfigSyncServerRpc)); if (!instance.syncUnlockEverything) { return; } { foreach (UnlockableEmote allUnlockableEmote in StartOfRoundPatcher.allUnlockableEmotes) { StartOfRoundPatcher.UnlockEmoteLocal(allUnlockableEmote); } return; } } foreach (UnlockableEmote allUnlockableEmote2 in StartOfRoundPatcher.allUnlockableEmotes) { StartOfRoundPatcher.UnlockEmoteLocal(allUnlockableEmote2); } NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("TooManyEmotes-OnRequestConfigSyncClientRpc", new HandleNamedMessageDelegate(OnRequestConfigSyncClientRpc)); RequestConfigSync(); } public static void RequestConfigSync() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) if (NetworkManager.Singleton.IsClient) { Plugin.Log("Requesting config sync from server"); FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(0, (Allocator)2, -1); NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("TooManyEmotes-OnRequestConfigSyncServerRpc", 0uL, val, (NetworkDelivery)3); } else { Plugin.LogError("Failed to send unlocked emote update to server."); } } private static void OnRequestConfigSyncServerRpc(ulong clientId, FastBufferReader reader) { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) if (NetworkManager.Singleton.IsServer) { Plugin.Log("Receiving config sync request from client: " + clientId); syncedClients.Add(clientId); SyncManager.syncedClients.Remove(clientId); byte[] array = SerializeConfigToByteArray(instance); FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(4 + array.Length, (Allocator)2, -1); int num = array.Length; ((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteBytesSafe(array, -1, 0); NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("TooManyEmotes-OnRequestConfigSyncClientRpc", clientId, val, (NetworkDelivery)3); } } private static void OnRequestConfigSyncClientRpc(ulong clientId, FastBufferReader reader) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: 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_00b7: Unknown result type (might be due to invalid IL or missing references) if (!NetworkManager.Singleton.IsClient) { return; } int num = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives)); if (((FastBufferReader)(ref reader)).TryBeginRead(num)) { Plugin.Log("Receiving config sync from server."); byte[] data = new byte[num]; ((FastBufferReader)(ref reader)).ReadBytesSafe(ref data, num, 0); instance = DeserializeFromByteArray(data); if (instance.syncUnlockEverything) { instance.syncShareEverything = true; } syncMaskedEnemyEmoteRandomDelay = new Vector2(instance.syncMaskedEnemyEmoteRandomDelayMin, instance.syncMaskedEnemyEmoteRandomDelayMax); syncMaskedEnemyEmoteRandomDuration = new Vector2(instance.syncMaskedEnemyEmoteRandomDurationMin, instance.syncMaskedEnemyEmoteRandomDurationMax); isSynced = true; if (StartOfRoundPatcher.allUnlockableEmotes != null && StartOfRoundPatcher.unlockedEmotes != null) { StartOfRoundPatcher.ResetProgressLocal(); if (instance.syncUnlockEverything) { StartOfRoundPatcher.UnlockEmotesLocal(StartOfRoundPatcher.allUnlockableEmotes); } else { StartOfRoundPatcher.UnlockEmotesLocal(StartOfRoundPatcher.complementaryEmotes); } StartOfRoundPatcher.UpdateUnlockedFavoriteEmotes(); } } else { Plugin.LogError("Error receiving sync from server."); } } public static byte[] SerializeConfigToByteArray(ConfigSync config) { BinaryFormatter binaryFormatter = new BinaryFormatter(); MemoryStream memoryStream = new MemoryStream(); binaryFormatter.Serialize(memoryStream, config); return memoryStream.ToArray(); } public static ConfigSync DeserializeFromByteArray(byte[] data) { MemoryStream serializationStream = new MemoryStream(data); BinaryFormatter binaryFormatter = new BinaryFormatter(); return (ConfigSync)binaryFormatter.Deserialize(serializationStream); } } [HarmonyPatch] public static class SyncManager { public static bool requestedSync; public static bool isSynced; public static HashSet<ulong> syncedClients; [HarmonyPatch(typeof(StartOfRound), "Awake")] [HarmonyPostfix] public static void ResetValues() { isSynced = false; requestedSync = false; } [HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")] [HarmonyPostfix] public static void Init() { //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Expected O, but got Unknown //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Expected O, but got Unknown //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown isSynced = NetworkManager.Singleton.IsServer; requestedSync = NetworkManager.Singleton.IsServer; if (NetworkManager.Singleton.IsServer) { syncedClients = new HashSet<ulong>(); NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("TooManyEmotes-OnRequestSyncServerRpc", new HandleNamedMessageDelegate(OnRequestSyncServerRpc)); NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("TooManyEmotes-OnUnlockEmoteServerRpc", new HandleNamedMessageDelegate(OnUnlockEmoteServerRpc)); } else { NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("TooManyEmotes-OnRequestSyncClientRpc", new HandleNamedMessageDelegate(OnRequestSyncClientRpc)); NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("TooManyEmotes-OnUnlockEmoteClientRpc", new HandleNamedMessageDelegate(OnUnlockEmoteClientRpc)); NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("TooManyEmotes-OnRotateEmotesClientRpc", new HandleNamedMessageDelegate(RotateEmoteSelectionClientRpc)); } } [HarmonyPatch(typeof(PlayerControllerB), "Update")] [HarmonyPostfix] public static void RequestSyncAfterConfigUpdate(PlayerControllerB __instance) { if (!isSynced && !requestedSync && ConfigSync.isSynced && (Object)(object)__instance == (Object)(object)StartOfRound.Instance.localPlayerController) { SendSyncRequest(); requestedSync = true; } } public static void SendSyncRequest() { //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (NetworkManager.Singleton.IsClient) { Plugin.Log("Sending sync request to server."); FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(0,