using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using PEAKEmoteLib; using UnityEngine; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("FGStickerEmotes")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("2.3.0.0")] [assembly: AssemblyInformationalVersion("2.3.0")] [assembly: AssemblyProduct("FGStickerEmotes")] [assembly: AssemblyTitle("FGStickerEmotes")] [assembly: AssemblyVersion("2.3.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace FGStickerEmotes { internal sealed class EmoteBubble : MonoBehaviour { private static readonly Dictionary Active = new Dictionary(); private CharacterAnimations _owner; private Transform _target; private SpriteRenderer _renderer; private float _age; internal static void ShowFor(CharacterAnimations owner, Transform target, StickerAsset sticker) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown ClearFor(owner); GameObject val = new GameObject("FGStickerBubble"); SpriteRenderer val2 = val.AddComponent(); val2.sprite = sticker.Sprite; ((Renderer)val2).sortingOrder = 1000; if (Plugin.EnableSounds && (Object)(object)sticker.AudioClip != (Object)null) { AudioSource obj = val.AddComponent(); obj.clip = sticker.AudioClip; obj.volume = Plugin.SoundVolume; obj.spatialBlend = Plugin.SoundSpatialBlend; obj.playOnAwake = false; obj.Play(); } EmoteBubble emoteBubble = val.AddComponent(); emoteBubble._owner = owner; emoteBubble._target = target; emoteBubble._renderer = val2; emoteBubble.UpdateTransform(); Active[owner] = emoteBubble; } internal static void ClearFor(CharacterAnimations owner) { if (Active.TryGetValue(owner, out EmoteBubble value) && (Object)(object)value != (Object)null) { Object.Destroy((Object)(object)((Component)value).gameObject); } Active.Remove(owner); } internal static void ClearAll() { foreach (EmoteBubble value in Active.Values) { if ((Object)(object)value != (Object)null) { Object.Destroy((Object)(object)((Component)value).gameObject); } } Active.Clear(); } private void LateUpdate() { //IL_008c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_owner == (Object)null || (Object)(object)_target == (Object)null) { RemoveAndDestroy(); return; } _age += Time.deltaTime; float displaySeconds = Plugin.DisplaySeconds; if (_age >= displaySeconds) { RemoveAndDestroy(); return; } UpdateTransform(); float num = displaySeconds - _age; float num2 = ((num < 0.4f) ? Mathf.Clamp01(num / 0.4f) : 1f); _renderer.color = new Color(1f, 1f, 1f, num2); } private void UpdateTransform() { //IL_005e: 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_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_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: 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_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) float num = 1f; if (Plugin.AnimatePop && _age < 0.25f) { float num2 = Mathf.Clamp01(_age / 0.25f); num = Mathf.Sin(num2 * MathF.PI * 0.5f) * (1.15f - 0.15f * num2); } float num3 = Plugin.WorldScale * num; ((Component)this).transform.localScale = Vector3.one * num3; Bounds bounds = _renderer.sprite.bounds; float num4 = ((Bounds)(ref bounds)).extents.y * num3; Camera main = Camera.main; Vector3 val = (((Object)(object)main != (Object)null) ? ((Component)main).transform.right : Vector3.right); ((Component)this).transform.position = _target.position + Vector3.up * (Plugin.HeightOffset + num4) + val * Plugin.HorizontalOffset; if ((Object)(object)main != (Object)null) { ((Component)this).transform.rotation = ((Component)main).transform.rotation; } } private void RemoveAndDestroy() { if ((Object)(object)_owner != (Object)null) { Active.Remove(_owner); } Object.Destroy((Object)(object)((Component)this).gameObject); } } [HarmonyPatch(typeof(CharacterAnimations), "RPCA_PlayRemove")] internal static class EmoteBubblePatch { [HarmonyPrefix] [HarmonyPriority(600)] private static bool Prefix(CharacterAnimations __instance, string emoteName) { if (!Plugin.Stickers.TryGetValue(emoteName, out StickerAsset value)) { return true; } EmoteBubble.ShowFor(__instance, ResolveHead(__instance), value); return false; } private static Transform ResolveHead(CharacterAnimations animations) { Transform val = FindCharacterRoot(animations); Animator componentInChildren = ((Component)val).GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { if ((Object)(object)componentInChildren.avatar != (Object)null && componentInChildren.avatar.isHuman) { Transform boneTransform = componentInChildren.GetBoneTransform((HumanBodyBones)10); if ((Object)(object)boneTransform != (Object)null) { return boneTransform; } } Transform val2 = FindNamedHead(((Component)componentInChildren).transform); if ((Object)(object)val2 != (Object)null) { return val2; } } SkinnedMeshRenderer componentInChildren2 = ((Component)val).GetComponentInChildren(true); if ((Object)(object)componentInChildren2 != (Object)null && (Object)(object)componentInChildren2.rootBone != (Object)null) { Transform val3 = FindNamedHead(componentInChildren2.rootBone); if ((Object)(object)val3 != (Object)null) { return val3; } } return val; } private static Transform FindCharacterRoot(CharacterAnimations animations) { Component[] componentsInParent = ((Component)animations).GetComponentsInParent(true); foreach (Component val in componentsInParent) { if ((Object)(object)val != (Object)null && ((object)val).GetType().Name == "Character") { return val.transform; } } return ((Component)animations).transform; } private static Transform FindNamedHead(Transform root) { Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren(true); foreach (Transform val in componentsInChildren) { if (((Object)val).name.ToLowerInvariant().Contains("head")) { return val; } } return null; } } [BepInPlugin("MuTu.FGStickerEmotes", "FG Sticker Emotes", "2.3.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { private sealed class BuiltInSticker { internal string Id { get; } internal string FileName { get; } internal string EnglishName { get; } internal string JapaneseName { get; } internal BuiltInSticker(string id, string fileName, string englishName, string japaneseName) { Id = id; FileName = fileName; EnglishName = englishName; JapaneseName = japaneseName; } } public const string Guid = "MuTu.FGStickerEmotes"; public const string Name = "FG Sticker Emotes"; public const string Version = "2.3.0"; private static readonly BuiltInSticker[] BuiltIns = new BuiltInSticker[9] { new BuiltInSticker("MuTu_FingerHeart", "finger_heart.png", "Happy", "シアワセ"), new BuiltInSticker("MuTu_AwkwardSweat", "awkward_sweat.png", "Sad", "カナシイ"), new BuiltInSticker("MuTu_Angry", "angry.png", "Angry", "イカリ"), new BuiltInSticker("MuTu_ExcitedCrown", "excited_crown.png", "Surprised", "ビックリ"), new BuiltInSticker("MuTu_Turkey", "turkey.png", "Turkey", "ターキー"), new BuiltInSticker("MuTu_Help", "help.png", "Help", "助けて"), new BuiltInSticker("MuTu_OnMyWay", "on_my_way.png", "On My Way", "今いくよ"), new BuiltInSticker("MuTu_OverHere", "over_here.png", "Over Here", "こっちだよ"), new BuiltInSticker("MuTu_Thanks", "thanks.png", "Thanks", "ありがとう") }; private static readonly Dictionary StickerAssets = new Dictionary(StringComparer.Ordinal); private static ConfigEntry DisplaySecondsEntry = null; private static ConfigEntry WorldScaleEntry = null; private static ConfigEntry HeightOffsetEntry = null; private static ConfigEntry HorizontalOffsetEntry = null; private static ConfigEntry AnimatePopEntry = null; private static ConfigEntry LoadCustomStickersEntry = null; private static ConfigEntry EnableSoundsEntry = null; private static ConfigEntry SoundVolumeEntry = null; private static ConfigEntry SoundSpatialBlendEntry = null; private static ConfigEntry PositionStepEntry = null; private static ConfigEntry MoveUpShortcutEntry = null; private static ConfigEntry MoveDownShortcutEntry = null; private static ConfigEntry MoveLeftShortcutEntry = null; private static ConfigEntry MoveRightShortcutEntry = null; private static ConfigEntry ResetPositionShortcutEntry = null; private Harmony? _harmony; internal static ManualLogSource Log { get; private set; } = null; internal static IReadOnlyDictionary Stickers => StickerAssets; internal static float DisplaySeconds => DisplaySecondsEntry.Value; internal static float WorldScale => WorldScaleEntry.Value; internal static float HeightOffset => HeightOffsetEntry.Value; internal static float HorizontalOffset => HorizontalOffsetEntry.Value; internal static bool AnimatePop => AnimatePopEntry.Value; internal static bool EnableSounds => EnableSoundsEntry.Value; internal static float SoundVolume => SoundVolumeEntry.Value; internal static float SoundSpatialBlend => SoundSpatialBlendEntry.Value; private void Awake() { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; BindConfiguration(); string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "icons"); BuiltInSticker[] builtIns = BuiltIns; foreach (BuiltInSticker builtInSticker in builtIns) { RegisterSticker(text, builtInSticker.Id, builtInSticker.FileName, builtInSticker.EnglishName, builtInSticker.JapaneseName); } if (LoadCustomStickersEntry.Value) { RegisterCustomStickers(text); } ((MonoBehaviour)this).StartCoroutine(LoadStickerSounds(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "sounds"))); _harmony = new Harmony("MuTu.FGStickerEmotes"); _harmony.PatchAll(); Log.LogInfo((object)string.Format("{0} {1} loaded with {2} stickers.", "FG Sticker Emotes", "2.3.0", StickerAssets.Count)); } private void OnDestroy() { Harmony? harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } EmoteBubble.ClearAll(); foreach (StickerAsset value in StickerAssets.Values) { Object.Destroy((Object)(object)value.Sprite); Object.Destroy((Object)(object)value.Texture); if ((Object)(object)value.AudioClip != (Object)null) { Object.Destroy((Object)(object)value.AudioClip); } } StickerAssets.Clear(); } private void Update() { //IL_0011: 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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) float num = 0f; float num2 = 0f; KeyboardShortcut value = MoveLeftShortcutEntry.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { num -= PositionStepEntry.Value; } value = MoveRightShortcutEntry.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { num += PositionStepEntry.Value; } value = MoveDownShortcutEntry.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { num2 -= PositionStepEntry.Value; } value = MoveUpShortcutEntry.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { num2 += PositionStepEntry.Value; } if (!Mathf.Approximately(num, 0f) || !Mathf.Approximately(num2, 0f)) { HorizontalOffsetEntry.Value = Mathf.Clamp(HorizontalOffsetEntry.Value + num, -3f, 3f); HeightOffsetEntry.Value = Mathf.Clamp(HeightOffsetEntry.Value + num2, 0f, 3f); ((BaseUnityPlugin)this).Config.Save(); Log.LogInfo((object)$"Sticker position: horizontal={HorizontalOffsetEntry.Value:0.00}, height={HeightOffsetEntry.Value:0.00}"); } value = ResetPositionShortcutEntry.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { HorizontalOffsetEntry.Value = 0f; HeightOffsetEntry.Value = 0.75f; ((BaseUnityPlugin)this).Config.Save(); Log.LogInfo((object)"Sticker position reset."); } } private void BindConfiguration() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Expected O, but got Unknown //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Expected O, but got Unknown //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Expected O, but got Unknown //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Expected O, but got Unknown //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Unknown result type (might be due to invalid IL or missing references) DisplaySecondsEntry = ((BaseUnityPlugin)this).Config.Bind("Display", "Duration", 5f, new ConfigDescription("Seconds each sticker remains visible.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 15f), Array.Empty())); WorldScaleEntry = ((BaseUnityPlugin)this).Config.Bind("Display", "Scale", 1.25f, new ConfigDescription("Sticker size in world space.", (AcceptableValueBase)(object)new AcceptableValueRange(0.25f, 4f), Array.Empty())); HeightOffsetEntry = ((BaseUnityPlugin)this).Config.Bind("Display", "HeightOffset", 0.75f, new ConfigDescription("World-space gap between the detected head point and the bottom of the sticker.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 3f), Array.Empty())); HorizontalOffsetEntry = ((BaseUnityPlugin)this).Config.Bind("Display", "HorizontalOffset", 0f, new ConfigDescription("Camera-relative horizontal sticker offset.", (AcceptableValueBase)(object)new AcceptableValueRange(-3f, 3f), Array.Empty())); AnimatePopEntry = ((BaseUnityPlugin)this).Config.Bind("Display", "AnimatePop", true, "Animate stickers when they appear."); LoadCustomStickersEntry = ((BaseUnityPlugin)this).Config.Bind("Stickers", "LoadCustomPngFiles", true, "Register additional PNG files placed in the icons folder."); EnableSoundsEntry = ((BaseUnityPlugin)this).Config.Bind("Sound", "Enabled", true, "Play a sound when a sticker appears."); SoundVolumeEntry = ((BaseUnityPlugin)this).Config.Bind("Sound", "Volume", 0.8f, new ConfigDescription("Sticker sound volume.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); SoundSpatialBlendEntry = ((BaseUnityPlugin)this).Config.Bind("Sound", "SpatialBlend", 1f, new ConfigDescription("0 is 2D and 1 is fully positional 3D audio.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); PositionStepEntry = ((BaseUnityPlugin)this).Config.Bind("Position Controls", "Step", 0.1f, new ConfigDescription("Distance moved by each position shortcut press.", (AcceptableValueBase)(object)new AcceptableValueRange(0.01f, 0.5f), Array.Empty())); MoveUpShortcutEntry = ((BaseUnityPlugin)this).Config.Bind("Position Controls", "MoveUp", new KeyboardShortcut((KeyCode)273, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), "Move stickers up."); MoveDownShortcutEntry = ((BaseUnityPlugin)this).Config.Bind("Position Controls", "MoveDown", new KeyboardShortcut((KeyCode)274, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), "Move stickers down."); MoveLeftShortcutEntry = ((BaseUnityPlugin)this).Config.Bind("Position Controls", "MoveLeft", new KeyboardShortcut((KeyCode)276, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), "Move stickers left."); MoveRightShortcutEntry = ((BaseUnityPlugin)this).Config.Bind("Position Controls", "MoveRight", new KeyboardShortcut((KeyCode)275, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), "Move stickers right."); ResetPositionShortcutEntry = ((BaseUnityPlugin)this).Config.Bind("Position Controls", "Reset", new KeyboardShortcut((KeyCode)278, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), "Reset sticker position."); } private void RegisterCustomStickers(string iconDirectory) { if (!Directory.Exists(iconDirectory)) { return; } HashSet hashSet = new HashSet(BuiltIns.Select((BuiltInSticker sticker) => sticker.FileName), StringComparer.OrdinalIgnoreCase); foreach (string item in Directory.GetFiles(iconDirectory, "*.png").OrderBy((string path) => path, StringComparer.OrdinalIgnoreCase)) { string fileName = Path.GetFileName(item); if (!hashSet.Contains(fileName)) { string text = Path.GetFileNameWithoutExtension(item).Replace('_', ' ').Trim(); string id = "MuTu_Custom_" + SanitizeId(Path.GetFileNameWithoutExtension(item)); RegisterSticker(iconDirectory, id, fileName, text, text); } } } private void RegisterSticker(string directory, string id, string fileName, string englishName, string japaneseName) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Expected O, but got Unknown //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Expected O, but got Unknown string text = Path.Combine(directory, fileName); if (!File.Exists(text)) { Log.LogWarning((object)("Sticker icon not found: " + text)); return; } try { Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false) { name = "FGSticker_" + id + "_Texture", filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1 }; if (!ImageConversion.LoadImage(val, File.ReadAllBytes(text), false)) { Object.Destroy((Object)(object)val); Log.LogWarning((object)("Could not decode sticker icon: " + text)); return; } Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), (float)((Texture)val).width); ((Object)val2).name = "FGSticker_" + id + "_Sprite"; AnimationClip val3 = new AnimationClip { name = id, frameRate = 30f }; Emote val4 = new Emote(id, val3, val2, (EmoteType)0, true); val4.AddLocalization(englishName, (Language)0); val4.AddLocalization(japaneseName, (Language)11); BaseUnityPluginExtensions.RegisterEmote((BaseUnityPlugin)(object)this, val4); StickerAssets.Add(val4.Name, new StickerAsset(val, val2, Path.GetFileNameWithoutExtension(fileName))); } catch (Exception arg) { Log.LogError((object)$"Failed to register sticker '{fileName}': {arg}"); } } private IEnumerator LoadStickerSounds(string soundDirectory) { if (!Directory.Exists(soundDirectory)) { yield break; } foreach (StickerAsset asset in StickerAssets.Values) { string soundPath = FindSoundFile(soundDirectory, asset.SoundBaseName); if (soundPath != null) { AudioType val = (AudioType)(Path.GetExtension(soundPath).Equals(".wav", StringComparison.OrdinalIgnoreCase) ? 20 : 14); UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(new Uri(soundPath).AbsoluteUri, val); yield return request.SendWebRequest(); if ((int)request.result == 1) { asset.AudioClip = DownloadHandlerAudioClip.GetContent(request); ((Object)asset.AudioClip).name = "FGSticker_" + asset.SoundBaseName + "_Audio"; } else { Log.LogWarning((object)("Could not load sticker sound '" + soundPath + "': " + request.error)); } request.Dispose(); } } } private static string? FindSoundFile(string directory, string baseName) { string text = Path.Combine(directory, baseName + ".ogg"); if (File.Exists(text)) { return text; } string text2 = Path.Combine(directory, baseName + ".wav"); if (!File.Exists(text2)) { return null; } return text2; } private static string SanitizeId(string value) { StringBuilder stringBuilder = new StringBuilder(value.Length); foreach (char c in value) { stringBuilder.Append(char.IsLetterOrDigit(c) ? c : '_'); } return stringBuilder.ToString(); } } internal sealed class StickerAsset { internal Texture2D Texture { get; } internal Sprite Sprite { get; } internal string SoundBaseName { get; } internal AudioClip? AudioClip { get; set; } internal StickerAsset(Texture2D texture, Sprite sprite, string soundBaseName) { Texture = texture; Sprite = sprite; SoundBaseName = soundBaseName; } } }