using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using UnityEngine; using UnityEngine.Audio; using UnityEngine.Networking; using WKLib.API.Input; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("WhiteKnuckleEmotes")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("My first plugin")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("WhiteKnuckleEmotes")] [assembly: AssemblyTitle("WhiteKnuckleEmotes")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace WhiteKnuckleEmotes { public static class Patches { [Serializable] public class EmoteData { [Serializable] public class HandEmote { public string id; public string sound; } public string id; public List emotes; } [HarmonyPatch(typeof(ENT_Player), "Awake")] private class Patch_ENT_Player_Awake { private static void Postfix(ENT_Player __instance) { _playingEmote = new bool[__instance.hands.Length]; } } [HarmonyPatch(typeof(CL_CosmeticManager), "CreateHandCosmetics")] private class Patch_CL_CosmeticManager_CreateHandCosmetics { private static void Postfix(CL_CosmeticManager __instance, string subdir, List jsonList, Dictionary ___cosmeticHandDict) { foreach (string json in jsonList) { string text = File.ReadAllText(json); EmoteData emoteData = JsonConvert.DeserializeObject(text); if (!___cosmeticHandDict.TryGetValue(emoteData.id, out var value) || value.cosmeticData.emotes == null || value.cosmeticData.emotes.Count == 0) { continue; } List palettes = value.cosmeticData.palettes; bool flag = palettes != null && palettes.Count > 0; for (int i = 0; i < value.cosmeticData.emotes.Count; i++) { HandEmote val = value.cosmeticData.emotes[i]; EmoteData.HandEmote handEmote = emoteData.emotes[i]; if (!string.IsNullOrEmpty(val.spriteName)) { Sprite val2 = RuntimeSpriteImporter.LoadSpriteFromFile(Path.Combine(subdir, "Sprites", val.spriteName + ".png"), 100f, (FilterMode)0, false, flag); ((Object)val2).name = val.spriteName; val.sprite = val2; if (!string.IsNullOrEmpty(handEmote.sound)) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(LoadAudioClip(Path.Combine(subdir, "Sounds", handEmote.sound + ".wav"), emoteData.id, handEmote.id)); } } } } } private static IEnumerator LoadAudioClip(string path, string cosmeticId, string emoteId) { UnityWebRequest uwr = UnityWebRequestMultimedia.GetAudioClip("file://" + path, (AudioType)20); try { yield return uwr.SendWebRequest(); if ((int)uwr.result != 1) { Plugin.Log.LogError((object)uwr.error); yield break; } AudioClip content = DownloadHandlerAudioClip.GetContent(uwr); ((Object)content).name = Path.GetFileNameWithoutExtension(path); Plugin.Log.LogInfo((object)("Loaded Clip: " + ((Object)content).name)); if (!_emoteSounds.ContainsKey(cosmeticId)) { _emoteSounds.Add(cosmeticId, new Dictionary()); } if (!_emoteSounds[cosmeticId].ContainsKey(emoteId)) { _emoteSounds[cosmeticId].Add(emoteId, content); } } finally { ((IDisposable)uwr)?.Dispose(); } } } [HarmonyPatch(typeof(ENT_Player), "HandAnimation")] private class Patch_ENT_Player_HandAnimation { private static void Postfix(ENT_Player __instance, Hand curhand, bool interacting, bool canInteract) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Invalid comparison between Unknown and I4 //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) if (interacting || !canInteract || !curhand.IsFree()) { if (_playingEmote[curhand.id]) { curhand.GetViewSway().targetOffset = Vector3.zero; _playingEmote[curhand.id] = false; } } else { if (curhand.currentCosmetics == null || curhand.currentCosmetics.Count == 0) { return; } List> list = ((curhand.id == 0) ? Plugin.EmoteKeysLeft : Plugin.EmoteKeysRight); foreach (Cosmetic_HandItem currentCosmetic in curhand.currentCosmetics) { if (currentCosmetic.cosmeticData.emotes == null || currentCosmetic.cosmeticData.emotes.Count == 0) { continue; } bool flag = false; for (int i = 0; i < Mathf.Min(currentCosmetic.cosmeticData.emotes.Count, 10); i++) { if ((int)list[i].Value == 0 || !InputUtility.GetKeyDown(list[i].Value)) { continue; } HandEmote val = currentCosmetic.cosmeticData.emotes[i]; curhand.SetSprite(val.sprite, (Sprite)null); curhand.GetViewSway().targetOffset = Vector3.Scale(val.position, ((Component)curhand.handSprite).transform.localScale); if (!_playingEmote[curhand.id] && _emoteSounds.ContainsKey(currentCosmetic.cosmeticData.id) && _emoteSounds[currentCosmetic.cosmeticData.id].ContainsKey(val.id)) { AudioClip val2 = _emoteSounds[currentCosmetic.cosmeticData.id][val.id]; if (Object.op_Implicit((Object)(object)val2)) { AudioManager.PlaySound(val2, curhand.handModel, 1f, 1f, 1f, false, 1f, (AudioMixerGroup)null, ""); } } _playingEmote[curhand.id] = true; flag = true; break; } if (!flag && _playingEmote[curhand.id]) { curhand.GetViewSway().targetOffset = Vector3.zero; _playingEmote[curhand.id] = false; } } } } } private static bool[] _playingEmote; private static Dictionary> _emoteSounds = new Dictionary>(); } [BepInPlugin("WhiteKnuckleEmotes", "WhiteKnuckleEmotes", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public static readonly List> EmoteKeysLeft = new List>(); public static readonly List> EmoteKeysRight = new List>(); public const int MaxEmotes = 10; public static Plugin Instance { get; private set; } public static ManualLogSource Log { get; private set; } private void Awake() { //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; for (int i = 0; i < 10; i++) { EmoteKeysLeft.Add(((BaseUnityPlugin)this).Config.Bind("General.KeyBinds", "EmoteKeyLeft" + i, (KeyCode)0, (ConfigDescription)null)); EmoteKeysRight.Add(((BaseUnityPlugin)this).Config.Bind("General.KeyBinds", "EmoteKeyRight" + i, (KeyCode)0, (ConfigDescription)null)); } Harmony val = new Harmony("WhiteKnuckleEmotes.patch"); val.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin WhiteKnuckleEmotes is loaded!"); } } public static class PluginInfo { public const string PLUGIN_GUID = "WhiteKnuckleEmotes"; public const string PLUGIN_NAME = "WhiteKnuckleEmotes"; public const string PLUGIN_VERSION = "1.0.0"; } }