using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using PEAKLib.Core; using Photon.Pun; using Photon.Realtime; using PhotonCustomPropsUtils; using TMPro; using UnityEngine; using UnityEngine.Audio; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.Rendering; using UnityEngine.SceneManagement; using UnityEngine.UI; using Zorro.Core; using Zorro.Settings; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("Blind Deaf and Mute Challenge")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Blind Deaf and Mute Challenge")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("c2254fa2-c18c-428a-b0c2-1c7b26f94967")] [assembly: AssemblyFileVersion("1.1.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.0.0")] [module: UnverifiableCode] 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; } } } namespace BlindDeafMuteChallenge { internal static class BdmAbilityHud { private sealed class AbilityWidget { internal GameObject Root; internal Image OuterFill; internal Image OuterEmpty; internal Image InnerFill; internal Image InnerEmpty; internal GameObject InnerRoot; internal Image Icon; internal TextMeshProUGUI Label; internal CanvasGroup Group; } private const int SortOrder = 6000; private const float Gap = 100f; private const float IconSize = 32f; private const float InnerScale = 0.72f; private static readonly Color DefaultCooldownColor = new Color(1f, 0.82f, 0.15f, 1f); private static readonly Color DefaultUseColor = new Color(0.72f, 0.35f, 0.95f, 1f); private static GameObject _root; private static Canvas _canvas; private static RectTransform _row; private static AbilityWidget _sonar; private static AbilityWidget _hook; private static AbilityWidget _detection; private static Sprite _sonarSprite; private static Sprite _hookSprite; private static Sprite _detectionSprite; private static int _hookIconItemId = int.MinValue; private static bool _detectionIconTried; private static bool _loggedMissingTemplate; private static bool _loggedCloned; internal static void EnsureCreated() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown //IL_00bf: 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_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_root != (Object)null)) { _root = new GameObject("BDM_AbilityHud"); Object.DontDestroyOnLoad((Object)(object)_root); _canvas = _root.AddComponent(); _canvas.renderMode = (RenderMode)0; _canvas.sortingOrder = 6000; CanvasScaler val = _root.AddComponent(); val.uiScaleMode = (ScaleMode)1; val.referenceResolution = new Vector2(1920f, 1080f); GameObject val2 = new GameObject("Row"); val2.transform.SetParent(_root.transform, false); _row = val2.AddComponent(); _row.anchorMin = new Vector2(0.5f, 0f); _row.anchorMax = new Vector2(0.5f, 0f); _row.pivot = new Vector2(0.5f, 0f); _row.anchoredPosition = new Vector2(0f, 0f); _row.sizeDelta = new Vector2(280f, 140f); _root.SetActive(false); } } internal static void Shutdown() { if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); _root = null; } _canvas = null; _row = null; _sonar = null; _hook = null; _detection = null; _sonarSprite = null; _hookSprite = null; _detectionSprite = null; _hookIconItemId = int.MinValue; _detectionIconTried = false; _loggedMissingTemplate = false; _loggedCloned = false; } internal static void Tick() { EnsureCreated(); BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; if ((Object)(object)instance == (Object)null || !BdmModAuthorizationService.CanUseSyncedChallenge()) { if ((Object)(object)_root != (Object)null && _root.activeSelf) { _root.SetActive(false); } return; } BdmSyncedSettings effectiveSettings = instance.GetEffectiveSettings(); bool flag = instance.IsBlindEffectWanted() && effectiveSettings.EnableSonar; bool flag2 = instance.IsLocalMuteActive && effectiveSettings.EnableRescueHook; bool flag3 = instance.IsLocalDeafActive && effectiveSettings.EnableDetection; if (!flag && !flag2 && !flag3) { if (_root.activeSelf) { _root.SetActive(false); } return; } if (!EnsureWidgetsFromVanillaTemplate()) { if (_root.activeSelf) { _root.SetActive(false); } return; } if (!_root.activeSelf) { _root.SetActive(true); } EnsureIcons(); ApplyLiveLayout(); if (_sonar != null) { _sonar.Root.SetActive(flag); if (flag) { UpdateWidget(_sonar, BdmBlindSonar.HudCooldownFill, BdmBlindSonar.HudUseFill, BdmBlindSonar.IsReady, BdmBlindSonar.IsActive, "Sonar"); } } if (_detection != null) { _detection.Root.SetActive(flag3); if (flag3) { UpdateWidget(_detection, BdmDeafDetection.HudCooldownFill, BdmDeafDetection.HudUseFill, BdmDeafDetection.IsReady, BdmDeafDetection.IsActive, "Detection"); } } if (_hook != null) { _hook.Root.SetActive(flag2); if (flag2) { UpdateWidget(_hook, BdmMuteRescueHook.HudCooldownFill, BdmMuteRescueHook.HudUseFill, BdmMuteRescueHook.IsReady, BdmMuteRescueHook.IsActive, "Lifeline"); } } LayoutWidgets(flag, flag3, flag2); } private static void ApplyLiveLayout() { //IL_007c: Unknown result type (might be due to invalid IL or missing references) BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; float num = (((Object)(object)instance != (Object)null) ? instance.AbilityHudPosX : 0f); float num2 = (((Object)(object)instance != (Object)null) ? instance.AbilityHudPosY : 0f); float labelY = (((Object)(object)instance != (Object)null) ? instance.AbilityHudLabelOffsetY : 54f); float fontSize = (((Object)(object)instance != (Object)null) ? instance.AbilityHudLabelFontSize : 30f); if ((Object)(object)_row != (Object)null) { _row.anchoredPosition = new Vector2(num, num2); } ApplyLabelStyle(_sonar, labelY, fontSize); ApplyLabelStyle(_detection, labelY, fontSize); ApplyLabelStyle(_hook, labelY, fontSize); } private static void ApplyLabelStyle(AbilityWidget widget, float labelY, float fontSize) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)widget?.Label == (Object)null)) { RectTransform rectTransform = ((TMP_Text)widget.Label).rectTransform; rectTransform.anchoredPosition = new Vector2(0f, labelY); rectTransform.sizeDelta = new Vector2(Mathf.Max(160f, fontSize * 7.5f), Mathf.Max(22f, fontSize + 6f)); ((TMP_Text)widget.Label).fontSize = fontSize; BdmGameUiFont.Apply(widget.Label); } } private static Color GetCooldownColor() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; return ((Object)(object)instance != (Object)null) ? instance.AbilityHudCooldownColor : DefaultCooldownColor; } private static Color GetUseColor() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; return ((Object)(object)instance != (Object)null) ? instance.AbilityHudUseColor : DefaultUseColor; } private static bool EnsureWidgetsFromVanillaTemplate() { if (_sonar != null && _hook != null && _detection != null) { return true; } UI_UseItemProgress val = FindVanillaProgress(); if ((Object)(object)val == (Object)null || (Object)(object)val.fill == (Object)null || (Object)(object)val.empty == (Object)null) { if (!_loggedMissingTemplate) { _loggedMissingTemplate = true; BlindDeafMuteChallengePlugin.Instance?.LogDebug("[BlindDeafMute] Ability HUD waiting for vanilla UI_UseItemProgress..."); } return false; } if (_sonar == null) { _sonar = CloneDualRingWidget(val, "Sonar"); } if (_detection == null) { _detection = CloneDualRingWidget(val, "Detection"); } if (_hook == null) { _hook = CloneDualRingWidget(val, "RescueHook"); } if (_sonar == null || _hook == null || _detection == null) { return false; } if (!_loggedCloned) { _loggedCloned = true; BlindDeafMuteChallengePlugin.Instance?.LogAlways("[BlindDeafMute] Ability HUD: dual concentric UI_UseItemProgress rings ready."); } return true; } private static UI_UseItemProgress FindVanillaProgress() { try { if ((Object)(object)GUIManager.instance != (Object)null && (Object)(object)GUIManager.instance.hudCanvas != (Object)null) { UI_UseItemProgress componentInChildren = ((Component)GUIManager.instance.hudCanvas).GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { return componentInChildren; } } } catch { } return Object.FindFirstObjectByType((FindObjectsInactive)1); } private static AbilityWidget CloneDualRingWidget(UI_UseItemProgress template, string name) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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_008a: 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_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_010d: 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_0142: Expected O, but got Unknown //IL_0174: 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_0190: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Expected O, but got Unknown //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_0261: 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_02e0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)template == (Object)null || (Object)(object)_row == (Object)null) { return null; } GameObject val = new GameObject("BDM_" + name); val.transform.SetParent((Transform)(object)_row, false); RectTransform val2 = val.AddComponent(); Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0.5f, 0.5f); val2.anchorMax = val3; val2.anchorMin = val3; val2.pivot = new Vector2(0.5f, 0.5f); val2.anchoredPosition = Vector2.zero; val2.sizeDelta = new Vector2(120f, 140f); CanvasGroup val4 = val.AddComponent(); val4.blocksRaycasts = false; val4.interactable = false; if (!TryCloneRingPair(template, val.transform, "Outer", 1f, GetCooldownColor(), out var fill, out var empty, out var _)) { Object.Destroy((Object)(object)val); return null; } if (!TryCloneRingPair(template, val.transform, "Inner", 0.72f, GetUseColor(), out var fill2, out var empty2, out var cloneRoot2)) { Object.Destroy((Object)(object)val); return null; } GameObject val5 = new GameObject("BDM_Icon"); val5.transform.SetParent(val.transform, false); RectTransform val6 = val5.AddComponent(); ((Vector2)(ref val3))..ctor(0.5f, 0.5f); val6.anchorMax = val3; val6.anchorMin = val3; val6.pivot = new Vector2(0.5f, 0.5f); val6.sizeDelta = new Vector2(32f, 32f); val6.anchoredPosition = Vector2.zero; Image val7 = val5.AddComponent(); val7.preserveAspect = true; ((Graphic)val7).raycastTarget = false; ((Graphic)val7).color = Color.white; GameObject val8 = new GameObject("BDM_Label"); val8.transform.SetParent(val.transform, false); RectTransform val9 = val8.AddComponent(); val9.anchorMin = new Vector2(0.5f, 0f); val9.anchorMax = new Vector2(0.5f, 0f); val9.pivot = new Vector2(0.5f, 1f); val9.anchoredPosition = new Vector2(0f, 54f); val9.sizeDelta = new Vector2(220f, 36f); TextMeshProUGUI val10 = val8.AddComponent(); ((Graphic)val10).raycastTarget = false; ((TMP_Text)val10).enableWordWrapping = false; ((TMP_Text)val10).overflowMode = (TextOverflowModes)0; ((TMP_Text)val10).alignment = (TextAlignmentOptions)258; ((TMP_Text)val10).fontSize = 30f; ((TMP_Text)val10).fontStyle = (FontStyles)0; ((Graphic)val10).color = new Color(1f, 1f, 1f, 0.92f); ((TMP_Text)val10).text = ((name == "RescueHook") ? "Lifeline" : name); BdmGameUiFont.Apply(val10); return new AbilityWidget { Root = val, OuterFill = fill, OuterEmpty = empty, InnerFill = fill2, InnerEmpty = empty2, InnerRoot = cloneRoot2, Icon = val7, Label = val10, Group = val4 }; } private static bool TryCloneRingPair(UI_UseItemProgress template, Transform parent, string name, float scale, Color fillColor, out Image fill, out Image empty, out GameObject cloneRoot) { //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Invalid comparison between Unknown and I4 fill = null; empty = null; cloneRoot = null; GameObject val = Object.Instantiate(((Component)template).gameObject, parent, false); ((Object)val).name = name; val.SetActive(true); cloneRoot = val; UI_UseItemProgress component = val.GetComponent(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = false; } fill = (((Object)(object)component != (Object)null) ? component.fill : null); empty = (((Object)(object)component != (Object)null) ? component.empty : null); if ((Object)(object)fill == (Object)null || (Object)(object)empty == (Object)null) { Image[] componentsInChildren = val.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { if (!((Object)(object)componentsInChildren[i] == (Object)null)) { if ((Object)(object)fill == (Object)null && (int)componentsInChildren[i].type == 3) { fill = componentsInChildren[i]; } else if ((Object)(object)empty == (Object)null && (Object)(object)componentsInChildren[i] != (Object)(object)fill) { empty = componentsInChildren[i]; } } } } if ((Object)(object)fill == (Object)null) { Object.Destroy((Object)(object)val); cloneRoot = null; return false; } RectTransform component2 = val.GetComponent(); if ((Object)(object)component2 != (Object)null) { Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0.5f, 0.5f); component2.anchorMax = val2; component2.anchorMin = val2; component2.pivot = new Vector2(0.5f, 0.5f); component2.anchoredPosition = Vector2.zero; ((Transform)component2).localScale = Vector3.one * scale; } ConfigureRadial(fill, fillColor); if ((Object)(object)empty != (Object)null) { ((Behaviour)empty).enabled = true; ((Graphic)empty).raycastTarget = false; } return true; } private static void ConfigureRadial(Image fill, Color color) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Invalid comparison between Unknown and I4 //IL_0041: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)fill == (Object)null)) { if ((int)fill.type != 3) { fill.type = (Type)3; fill.fillMethod = (FillMethod)4; fill.fillOrigin = 2; fill.fillClockwise = true; } ((Graphic)fill).color = color; ((Behaviour)fill).enabled = true; ((Graphic)fill).raycastTarget = false; } } private static void LayoutWidgets(bool showSonar, bool showDetection, bool showHook) { List list = new List(3); if (showSonar && _sonar != null) { list.Add(_sonar); } if (showDetection && _detection != null) { list.Add(_detection); } if (showHook && _hook != null) { list.Add(_hook); } if (list.Count != 0) { if (list.Count == 1) { SetWidgetX(list[0], 0f); } else if (list.Count == 2) { float num = 50f; SetWidgetX(list[0], 0f - num); SetWidgetX(list[1], num); } else { SetWidgetX(list[0], -100f); SetWidgetX(list[1], 0f); SetWidgetX(list[2], 100f); } } } private static void SetWidgetX(AbilityWidget widget, float x) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) RectTransform component = widget.Root.GetComponent(); if ((Object)(object)component != (Object)null) { component.anchoredPosition = new Vector2(x, 24f); } } private static void UpdateWidget(AbilityWidget widget, float cooldownFill, float useFill, bool ready, bool active, string labelText) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0171: 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_0186: Unknown result type (might be due to invalid IL or missing references) cooldownFill = Mathf.Clamp01(cooldownFill); useFill = Mathf.Clamp01(useFill); if ((Object)(object)widget.Root != (Object)null) { Vector3 localScale = widget.Root.transform.localScale; if (((Vector3)(ref localScale)).sqrMagnitude < 0.01f) { widget.Root.transform.localScale = Vector3.one; } } if ((Object)(object)widget.OuterFill != (Object)null) { ConfigureRadial(widget.OuterFill, GetCooldownColor()); widget.OuterFill.fillAmount = cooldownFill; } if ((Object)(object)widget.OuterEmpty != (Object)null) { ((Behaviour)widget.OuterEmpty).enabled = true; } bool flag = active || useFill > 0.001f; if ((Object)(object)widget.InnerRoot != (Object)null) { widget.InnerRoot.SetActive(flag); } if (flag && (Object)(object)widget.InnerFill != (Object)null) { ConfigureRadial(widget.InnerFill, GetUseColor()); widget.InnerFill.fillAmount = useFill; } if ((Object)(object)widget.InnerEmpty != (Object)null) { ((Behaviour)widget.InnerEmpty).enabled = flag; } float a = (ready ? 1f : (active ? 0.95f : Mathf.Lerp(0.35f, 0.9f, cooldownFill))); if ((Object)(object)widget.Icon != (Object)null) { Color color = ((Graphic)widget.Icon).color; color.a = a; ((Graphic)widget.Icon).color = color; } if ((Object)(object)widget.Group != (Object)null) { widget.Group.alpha = (ready ? 1f : 0.95f); } if ((Object)(object)widget.Label != (Object)null) { if (((TMP_Text)widget.Label).text != labelText) { ((TMP_Text)widget.Label).text = labelText; } BdmGameUiFont.Apply(widget.Label); } } private static void EnsureIcons() { //IL_008a: 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_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) if (_sonar != null && (Object)(object)_sonar.Icon != (Object)null && (Object)(object)_sonarSprite == (Object)null) { Texture2D val = TryEmojiTex("1f987") ?? TryEmojiTex("1f3a7") ?? TryEmojiTex("1f50a") ?? TryEmojiTex("1f4e3"); if ((Object)(object)val != (Object)null) { _sonarSprite = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); _sonar.Icon.sprite = _sonarSprite; } } if (_detection != null && (Object)(object)_detection.Icon != (Object)null && !_detectionIconTried) { _detectionIconTried = true; Texture2D val2 = TryEmojiTex("1f9f3") ?? TryEmojiTex("1f4bc") ?? TryEmojiTex("1f6aa") ?? TryEmojiTex("1f4e6"); if ((Object)(object)val2 != (Object)null) { _detectionSprite = Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), new Vector2(0.5f, 0.5f), 100f); _detection.Icon.sprite = _detectionSprite; } } if (_hook != null && (Object)(object)_hook.Icon != (Object)null) { BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; int num = (((Object)(object)instance != (Object)null) ? instance.GetEffectiveSettings().RescueHookItemId : 167); if (num != _hookIconItemId) { TryAssignHookIcon(num); } } } private static void TryAssignHookIcon(int itemId) { //IL_008f: 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) try { Item val = default(Item); if (!ItemDatabase.TryGetItem((ushort)Mathf.Clamp(itemId, 1, 65535), ref val) || (Object)(object)val == (Object)null || val.UIData == null) { return; } Texture2D icon = val.UIData.GetIcon(); if (!((Object)(object)icon == (Object)null)) { if ((Object)(object)_hookSprite != (Object)null) { Object.Destroy((Object)(object)_hookSprite); _hookSprite = null; } _hookSprite = Sprite.Create(icon, new Rect(0f, 0f, (float)((Texture)icon).width, (float)((Texture)icon).height), new Vector2(0.5f, 0.5f), 100f); if ((Object)(object)_hook?.Icon != (Object)null) { _hook.Icon.sprite = _hookSprite; } _hookIconItemId = itemId; } } catch { } } private static Texture2D TryEmojiTex(string codeKey) { BdmEmojiCatalog.Entry entry = BdmEmojiCatalog.FindByCodeKey(codeKey); return (entry != null) ? BdmEmojiCatalog.GetTexture(entry) : null; } } internal static class BdmAssignmentSyncService { public const int SchemaVersion = 1; public const char PairSeparator = ';'; public const char KeyValueSeparator = '='; internal static bool HasRemoteAssignments { get; private set; } internal static Dictionary RemoteAssignments { get; private set; } = new Dictionary(); internal static void ClearRemoteAssignments() { HasRemoteAssignments = false; RemoteAssignments = new Dictionary(); } internal static void ApplyRemoteSnapshot(string payload) { if (!PhotonNetwork.IsMasterClient && !string.IsNullOrEmpty(payload)) { if (!TryDeserialize(payload, out var map)) { BlindDeafMuteChallengePlugin.Instance?.LogAlways("[BlindDeafMute] Failed to parse host assignment snapshot."); return; } HasRemoteAssignments = true; RemoteAssignments = map; BlindDeafMuteChallengePlugin.Instance?.LogAlways($"[BlindDeafMute] Applied host assignment snapshot ({map.Count} players)."); BlindDeafMuteChallengePlugin.Instance?.ApplyRemoteAssignments(map); } } internal static string Serialize(IReadOnlyDictionary assignments) { StringBuilder stringBuilder = new StringBuilder(128); Append(stringBuilder, "v", 1.ToString(CultureInfo.InvariantCulture)); if (assignments != null) { foreach (KeyValuePair assignment in assignments) { Append(stringBuilder, assignment.Key.ToString(CultureInfo.InvariantCulture), ((int)assignment.Value).ToString(CultureInfo.InvariantCulture)); } } return stringBuilder.ToString(); } internal static bool TryDeserialize(string payload, out Dictionary map) { map = new Dictionary(); if (string.IsNullOrEmpty(payload)) { return false; } if (payload.IndexOf('=') < 0 && payload.IndexOf(':') >= 0) { return TryDeserializeLegacy(payload, out map); } int result = 0; bool flag = false; string[] array = payload.Split(new char[1] { ';' }); foreach (string text in array) { if (string.IsNullOrEmpty(text)) { continue; } int num = text.IndexOf('='); if (num > 0) { string text2 = text.Substring(0, num); string s = text.Substring(num + 1); int result2; int result3; if (text2 == "v") { flag = int.TryParse(s, NumberStyles.Integer, CultureInfo.InvariantCulture, out result); } else if (int.TryParse(text2, NumberStyles.Integer, CultureInfo.InvariantCulture, out result2) && int.TryParse(s, NumberStyles.Integer, CultureInfo.InvariantCulture, out result3) && Enum.IsDefined(typeof(BlindDeafMuteChallengePlugin.AfflictionType), result3)) { map[result2] = (BlindDeafMuteChallengePlugin.AfflictionType)result3; } } } return flag && result == 1; } private static bool TryDeserializeLegacy(string payload, out Dictionary map) { map = new Dictionary(); string[] array = payload.Split(new char[1] { '|' }); foreach (string text in array) { string[] array2 = text.Split(new char[1] { ':' }); if (array2.Length == 2 && int.TryParse(array2[0], out var result)) { BlindDeafMuteChallengePlugin.AfflictionType result3; if (int.TryParse(array2[1], out var result2) && Enum.IsDefined(typeof(BlindDeafMuteChallengePlugin.AfflictionType), result2)) { result3 = (BlindDeafMuteChallengePlugin.AfflictionType)result2; } else if (!Enum.TryParse(array2[1], ignoreCase: true, out result3)) { continue; } map[result] = result3; } } return map.Count > 0; } private static void Append(StringBuilder builder, string key, string value) { if (builder.Length > 0) { builder.Append(';'); } builder.Append(key); builder.Append('='); builder.Append(value ?? string.Empty); } } internal static class BdmGameUiFont { private static TMP_FontAsset _cached; private static int _cachedSceneHandle = -1; internal static TMP_FontAsset Get() { //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_0009: Unknown result type (might be due to invalid IL or missing references) Scene activeScene = SceneManager.GetActiveScene(); int num = SceneHandle.op_Implicit(((Scene)(ref activeScene)).handle); if ((Object)(object)_cached != (Object)null && _cachedSceneHandle == num) { return _cached; } _cached = FindGameFont(); _cachedSceneHandle = num; return _cached; } internal static void Apply(TextMeshProUGUI text) { if (!((Object)(object)text == (Object)null)) { TMP_FontAsset val = Get(); if ((Object)(object)val != (Object)null) { ((TMP_Text)text).font = val; } ((TMP_Text)text).fontStyle = (FontStyles)0; } } private static TMP_FontAsset FindGameFont() { //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) try { GUIManager instance = GUIManager.instance; if ((Object)(object)instance != (Object)null) { TextMeshProUGUI componentInChildren = ((Component)instance).GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null && (Object)(object)((TMP_Text)componentInChildren).font != (Object)null) { return ((TMP_Text)componentInChildren).font; } } } catch { } try { TextMeshProUGUI val = Object.FindFirstObjectByType((FindObjectsInactive)1); if ((Object)(object)val != (Object)null && (Object)(object)((TMP_Text)val).font != (Object)null) { return ((TMP_Text)val).font; } } catch { } try { TextMeshProUGUI[] array = Resources.FindObjectsOfTypeAll(); foreach (TextMeshProUGUI val2 in array) { if ((Object)(object)val2 == (Object)null || (Object)(object)((TMP_Text)val2).font == (Object)null) { continue; } Scene scene = ((Component)val2).gameObject.scene; if (((Scene)(ref scene)).IsValid()) { scene = ((Component)val2).gameObject.scene; if (((Scene)(ref scene)).isLoaded) { return ((TMP_Text)val2).font; } } } } catch { } return null; } } internal static class BdmBlindMobility { [HarmonyPatch(typeof(CharacterMovement), "GetMovementForce")] private static class GetMovementForce_Patch { private static void Postfix(CharacterMovement __instance, ref float __result) { if (!((Object)(object)__instance == (Object)null) && WantBlindMobility(__instance.character)) { BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; float num = (((Object)(object)instance != (Object)null) ? Mathf.Clamp(instance.GetEffectiveSettings().BlindRunSpeedMultiplier, 1f, 3f) : 1.5f); __result *= num; } } } private static Character _climbAppliedTo; private static float _savedClimbMod = 1f; private static float _savedRopeMod = 1f; private static float _savedVineMod = 1f; private static bool _haveClimbSaved; internal static void Tick() { BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; Character localCharacter = Character.localCharacter; if (!((Object)(object)instance != (Object)null) || !instance.IsBlindEffectWanted() || !BdmModAuthorizationService.CanUseSyncedChallenge() || !instance.GetEffectiveSettings().EnableBlindMobility || !((Object)(object)localCharacter != (Object)null) || localCharacter.refs == null) { RestoreClimb(); } else { ApplyClimb(localCharacter, instance.GetEffectiveSettings()); } } internal static void Shutdown() { RestoreClimb(); } private static bool WantBlindMobility(Character character) { BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)character == (Object)null) { return false; } if ((Object)(object)character != (Object)(object)Character.localCharacter) { return false; } if (!instance.IsBlindEffectWanted() || !BdmModAuthorizationService.CanUseSyncedChallenge()) { return false; } return instance.GetEffectiveSettings().EnableBlindMobility; } private static void ApplyClimb(Character local, BdmSyncedSettings s) { if ((Object)(object)_climbAppliedTo != (Object)(object)local || !_haveClimbSaved) { RestoreClimb(); _savedClimbMod = (((Object)(object)local.refs.climbing != (Object)null) ? local.refs.climbing.climbSpeedMod : 1f); _savedRopeMod = (((Object)(object)local.refs.ropeHandling != (Object)null) ? local.refs.ropeHandling.climbSpeedMod : 1f); _savedVineMod = (((Object)(object)local.refs.vineClimbing != (Object)null) ? local.refs.vineClimbing.climbSpeedMod : 1f); _haveClimbSaved = true; _climbAppliedTo = local; } float num = Mathf.Clamp(s.BlindClimbSpeedMultiplier, 1f, 3f); if ((Object)(object)local.refs.climbing != (Object)null) { local.refs.climbing.climbSpeedMod = _savedClimbMod * num; } if ((Object)(object)local.refs.ropeHandling != (Object)null) { local.refs.ropeHandling.climbSpeedMod = _savedRopeMod * num; } if ((Object)(object)local.refs.vineClimbing != (Object)null) { local.refs.vineClimbing.climbSpeedMod = _savedVineMod * num; } } private static void RestoreClimb() { if (!_haveClimbSaved || (Object)(object)_climbAppliedTo == (Object)null) { _haveClimbSaved = false; _climbAppliedTo = null; return; } try { if ((Object)(object)_climbAppliedTo.refs?.climbing != (Object)null) { _climbAppliedTo.refs.climbing.climbSpeedMod = _savedClimbMod; } if ((Object)(object)_climbAppliedTo.refs?.ropeHandling != (Object)null) { _climbAppliedTo.refs.ropeHandling.climbSpeedMod = _savedRopeMod; } if ((Object)(object)_climbAppliedTo.refs?.vineClimbing != (Object)null) { _climbAppliedTo.refs.vineClimbing.climbSpeedMod = _savedVineMod; } } catch { } _haveClimbSaved = false; _climbAppliedTo = null; } } internal static class BdmBlindSonar { private static Coroutine _routine; private static float _cooldownStartedAt = -1f; private static float _useStartedAt = -1f; private static float _useDurationSeconds = 1f; private static bool _controllingBlackout; internal static bool IsActive => _routine != null; internal static bool IsControllingBlackout => _controllingBlackout; internal static bool IsOnCooldown => CooldownRemainingSeconds > 0f; internal static float CooldownRemainingSeconds { get { if (_cooldownStartedAt < 0f) { return 0f; } float liveCooldownSeconds = GetLiveCooldownSeconds(); return Mathf.Max(0f, _cooldownStartedAt + liveCooldownSeconds - Time.unscaledTime); } } internal static bool IsReady => !IsActive && !IsOnCooldown; internal static float CooldownDurationSeconds => GetLiveCooldownSeconds(); internal static float ActiveRemainingSeconds => (!IsActive) ? 0f : Mathf.Max(0f, _useStartedAt + _useDurationSeconds - Time.unscaledTime); internal static float HudCooldownFill { get { if (!IsOnCooldown && !IsActive) { return 1f; } float cooldownDurationSeconds = CooldownDurationSeconds; if (cooldownDurationSeconds <= 0.01f || _cooldownStartedAt < 0f) { return 1f; } return Mathf.Clamp01(1f - CooldownRemainingSeconds / cooldownDurationSeconds); } } internal static float HudUseFill { get { if (!IsActive || _useDurationSeconds <= 0.01f) { return 0f; } return Mathf.Clamp01(ActiveRemainingSeconds / _useDurationSeconds); } } internal static void TryActivate() { BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; if ((Object)(object)instance == (Object)null) { return; } if (!instance.IsBlindEffectWanted() || !BdmModAuthorizationService.CanUseSyncedChallenge()) { instance.LogAlways("[BlindDeafMute] Sonar is for Blind players only."); return; } BdmSyncedSettings effectiveSettings = instance.GetEffectiveSettings(); if (!effectiveSettings.EnableSonar) { instance.LogAlways("[BlindDeafMute] Sonar power is disabled by host."); return; } if (IsActive) { instance.LogAlways("[BlindDeafMute] Sonar already active."); return; } if (IsOnCooldown) { instance.LogAlways($"[BlindDeafMute] Sonar on cooldown ({CooldownRemainingSeconds:0}s left)."); return; } BdmSyncedSettings bdmSyncedSettings = effectiveSettings; int num = Mathf.Clamp(bdmSyncedSettings.SonarPingCount, 1, 10); float num2 = Mathf.Max(0.1f, bdmSyncedSettings.SonarVisionSeconds); float num3 = Mathf.Max(0f, bdmSyncedSettings.SonarFadeInSeconds); float num4 = Mathf.Max(0.1f, bdmSyncedSettings.SonarFadeOutSeconds); float num5 = Mathf.Max(0f, bdmSyncedSettings.SonarPingDelay); float num6 = Mathf.Max(1f, bdmSyncedSettings.SonarCooldownSeconds); _useDurationSeconds = Mathf.Max(0.5f, (float)num * (num3 + num2 + num4 + num5)); _useStartedAt = Time.unscaledTime; _cooldownStartedAt = Time.unscaledTime; _routine = ((MonoBehaviour)instance).StartCoroutine(RunSonar(num, num2, num3, num4, num5)); instance.LogAlways($"[BlindDeafMute] Sonar activated — {num} ping(s), ~{_useDurationSeconds:0.#}s use, cooldown {num6:0}s."); } internal static void Cancel() { BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; if (_routine != null && (Object)(object)instance != (Object)null) { ((MonoBehaviour)instance).StopCoroutine(_routine); _routine = null; } _controllingBlackout = false; StopCurseFx(); instance?.RestoreBlackoutAfterSonar(); } private static float GetLiveCooldownSeconds() { BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; if ((Object)(object)instance == (Object)null) { return 300f; } return Mathf.Max(1f, instance.GetEffectiveSettings().SonarCooldownSeconds); } private static IEnumerator RunSonar(int pings, float visionSeconds, float fadeInSeconds, float fadeOutSeconds, float pingDelaySeconds) { BlindDeafMuteChallengePlugin plugin = BlindDeafMuteChallengePlugin.Instance; _controllingBlackout = true; plugin?.EnsureBlackoutForSonar(); StartCurseFx(); for (int i = 0; i < pings; i++) { if ((Object)(object)plugin == (Object)null) { break; } if (!plugin.IsBlindEffectWanted()) { break; } yield return FadeBlackout(1f, 0f, fadeInSeconds); yield return (object)new WaitForSecondsRealtime(visionSeconds); yield return FadeBlackout(0f, 1f, fadeOutSeconds); if (pingDelaySeconds > 0f) { yield return (object)new WaitForSecondsRealtime(pingDelaySeconds); } } StopCurseFx(); _controllingBlackout = false; _routine = null; plugin?.RestoreBlackoutAfterSonar(); plugin?.LogAlways("[BlindDeafMute] Sonar finished."); } private static IEnumerator FadeBlackout(float from, float to, float duration) { BlindDeafMuteChallengePlugin plugin = BlindDeafMuteChallengePlugin.Instance; if ((Object)(object)plugin == (Object)null) { yield break; } if (duration <= 0.001f) { plugin.SetBlackoutAlpha(to); yield break; } float start = Time.unscaledTime; while (true) { float t = Mathf.Clamp01((Time.unscaledTime - start) / duration); plugin.SetBlackoutAlpha(Mathf.Lerp(from, to, t)); if (t >= 1f) { break; } yield return null; } plugin.SetBlackoutAlpha(to); } private static void StartCurseFx() { try { ScreenVFX val = (((Object)(object)GUIManager.instance != (Object)null) ? GUIManager.instance.curseSVFX : null); if ((Object)(object)val == (Object)null || (Object)(object)val.renderer == (Object)null) { BlindDeafMuteChallengePlugin.Instance?.LogAlways("[BlindDeafMute] Sonar: curseSVFX not found."); return; } ((Component)val).gameObject.SetActive(true); float num = 1f; if ((Object)(object)GUIManager.instance != (Object)null && GUIManager.instance.photosensitivity) { num *= 0.5f; } val.renderer.material.SetFloat(ScreenVFX.INTENSITY, num); } catch (Exception ex) { BlindDeafMuteChallengePlugin.Instance?.LogAlways("[BlindDeafMute] Sonar curse FX start failed: " + ex.Message); } } private static void StopCurseFx() { try { ScreenVFX val = (((Object)(object)GUIManager.instance != (Object)null) ? GUIManager.instance.curseSVFX : null); if (!((Object)(object)val == (Object)null)) { val.EndFX(); } } catch (Exception ex) { BlindDeafMuteChallengePlugin.Instance?.LogAlways("[BlindDeafMute] Sonar EndFX failed: " + ex.Message); } } } internal static class BdmDeafBonusLoot { private const string MagicConfetti = "BDM_DEAF_CONFETTI_V1"; private const float SpawnDelaySeconds = 0.15f; private const int MaxRerollsPerItem = 24; private static bool _hookedEvents; private static bool _hookedPhoton; private static ParticleSystem _confettiTemplate; private static GameObject _confettiTemplateRoot; private static SFX_PlayOneShot _successTemplate; internal static void Initialize() { if (!_hookedEvents) { GlobalEvents.OnLuggageOpened = (Action)Delegate.Combine(GlobalEvents.OnLuggageOpened, new Action(OnLuggageOpened)); _hookedEvents = true; BlindDeafMuteChallengePlugin.Instance?.LogAlways("[BlindDeafMute] Deaf bonus-loot hook ready."); } } internal static void Shutdown() { if (_hookedEvents) { GlobalEvents.OnLuggageOpened = (Action)Delegate.Remove(GlobalEvents.OnLuggageOpened, new Action(OnLuggageOpened)); _hookedEvents = false; } if (_hookedPhoton && PhotonNetwork.NetworkingClient != null) { PhotonNetwork.NetworkingClient.EventReceived -= OnPhotonEvent; _hookedPhoton = false; } if ((Object)(object)_confettiTemplateRoot != (Object)null) { Object.Destroy((Object)(object)_confettiTemplateRoot); _confettiTemplateRoot = null; } _confettiTemplate = null; _successTemplate = null; } internal static void TryWarmConfettiCache() { CacheConfettiTemplate(forceLog: false); } internal static void EnsurePhotonHooked() { if (!_hookedPhoton && PhotonNetwork.NetworkingClient != null) { PhotonNetwork.NetworkingClient.EventReceived += OnPhotonEvent; _hookedPhoton = true; } } private static void OnLuggageOpened(Luggage luggage, Character interactor) { BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)luggage == (Object)null || (Object)(object)interactor == (Object)null || !BdmModAuthorizationService.CanUseSyncedChallenge() || !instance.GetEffectiveSettings().EnableDeafBonusLoot || !PhotonNetwork.IsMasterClient || luggage is RespawnChest) { return; } int actorNumber = BlindDeafMuteChallengePlugin.GetActorNumber(interactor); if (instance.GetAssignedRole(actorNumber) != BlindDeafMuteChallengePlugin.AfflictionType.Deaf) { return; } BdmSyncedSettings effectiveSettings = instance.GetEffectiveSettings(); float num = NormalizeBonusLootChance(effectiveSettings.DeafBonusLootChance); if (!(num <= 0f) && !(Random.value > num)) { int count = Mathf.Clamp(effectiveSettings.DeafBonusLootCount, 1, 8); ushort[] array = ParseItemIds(effectiveSettings.DeafBonusLootItemIds); if (array.Length == 0) { instance.LogAlways("[BlindDeafMute] Deaf bonus loot skipped — empty/invalid ItemID list."); } else { ((MonoBehaviour)instance).StartCoroutine(SpawnBonusRoutine(luggage, array, count)); } } } private static IEnumerator SpawnBonusRoutine(Luggage luggage, ushort[] pool, int count) { yield return (object)new WaitForSeconds(0.15f); if ((Object)(object)luggage == (Object)null || !PhotonNetwork.IsMasterClient) { yield break; } BlindDeafMuteChallengePlugin plugin = BlindDeafMuteChallengePlugin.Instance; Vector3 basePos = luggage.Center(); Quaternion baseRot = ((Component)luggage).transform.rotation; int spawned = 0; for (int i = 0; i < count; i++) { if (!TryPickValidPrefab(pool, out var prefab, out var pickedId)) { plugin?.LogAlways("[BlindDeafMute] Deaf bonus loot: no valid ItemID left in host list."); break; } Vector3 pos = basePos + baseRot * new Vector3(Random.Range(-0.15f, 0.15f), 0.1f + 0.05f * (float)i, Random.Range(-0.15f, 0.15f)); GameObject go; try { go = PhotonNetwork.InstantiateItemRoom(((Object)((Component)prefab).gameObject).name, pos, baseRot); } catch (Exception ex) { plugin?.LogAlways($"[BlindDeafMute] Deaf bonus spawn failed id={pickedId}: {ex.Message}"); continue; } if ((Object)(object)go == (Object)null) { continue; } Item item = go.GetComponent(); if (!((Object)(object)item == (Object)null)) { try { ((Spawner)luggage).OffsetSpawn(item); ((Spawner)luggage).InitializePhysics(item); } catch (Exception ex2) { Exception ex3 = ex2; plugin?.LogDebug("[BlindDeafMute] Deaf bonus Offset/Physics: " + ex3.Message); } spawned++; plugin?.LogAlways($"[BlindDeafMute] Deaf bonus loot spawned id={pickedId} ({((Object)((Component)prefab).gameObject).name})."); prefab = null; } } if (spawned > 0) { Vector3 fxPos = luggage.Center() + Vector3.up * 0.4f; plugin?.LogAlways($"[BlindDeafMute] Deaf bonus confetti: requesting FX at {fxPos} (spawned={spawned})."); PlayConfettiAt(fxPos); BroadcastConfetti(fxPos); } } private static bool TryPickValidPrefab(ushort[] pool, out Item prefab, out ushort pickedId) { prefab = null; pickedId = 0; if (pool == null || pool.Length == 0) { return false; } int num = Mathf.Min(24, Mathf.Max(8, pool.Length * 3)); Item val = default(Item); for (int i = 0; i < num; i++) { ushort num2 = pool[Random.Range(0, pool.Length)]; if (ItemDatabase.TryGetItem(num2, ref val) && !((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).gameObject == (Object)null)) { prefab = val; pickedId = num2; return true; } } return false; } internal static float NormalizeBonusLootChance(float raw) { if (float.IsNaN(raw) || float.IsInfinity(raw)) { return 0f; } if (raw > 1f) { raw *= 0.01f; } if (raw < 0f) { return 0f; } if (raw > 1f) { return 1f; } return raw; } internal static ushort[] ParseItemIds(string raw) { if (string.IsNullOrWhiteSpace(raw)) { return Array.Empty(); } string[] array = raw.Split(new char[4] { ',', ';', ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); List list = new List(array.Length); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length != 0 && ushort.TryParse(text, out var result)) { list.Add(result); } } return list.ToArray(); } internal static string SanitizeItemIdsForSync(string raw) { ushort[] array = ParseItemIds(raw); if (array.Length == 0) { return string.Empty; } return string.Join(",", Array.ConvertAll(array, (ushort id) => id.ToString())); } private static void BroadcastConfetti(Vector3 pos) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) EnsurePhotonHooked(); if (PhotonNetwork.InRoom) { object[] array = new object[4] { "BDM_DEAF_CONFETTI_V1", pos.x, pos.y, pos.z }; RaiseEventOptions val = new RaiseEventOptions { Receivers = (ReceiverGroup)0 }; PhotonNetwork.RaiseEvent(BdmEmojiNet.EventCode, (object)array, val, SendOptions.SendReliable); } } private static void OnPhotonEvent(EventData photonEvent) { //IL_0087: Unknown result type (might be due to invalid IL or missing references) if (photonEvent == null || photonEvent.Code != BdmEmojiNet.EventCode || !(photonEvent.CustomData is object[] array) || array.Length < 4 || !(array[0] is string a) || !string.Equals(a, "BDM_DEAF_CONFETTI_V1", StringComparison.Ordinal)) { return; } try { float num = Convert.ToSingle(array[1]); float num2 = Convert.ToSingle(array[2]); float num3 = Convert.ToSingle(array[3]); PlayConfettiAt(new Vector3(num, num2, num3)); } catch { } } internal static void PlayConfettiAt(Vector3 worldPos) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; CacheConfettiTemplate(forceLog: true); bool flag = (Object)(object)_confettiTemplate != (Object)null && (Object)(object)_confettiTemplateRoot != (Object)null; instance?.LogDebug($"[BlindDeafMute] Confetti PlayConfettiAt pos={worldPos} " + string.Format("templateOk={0} root={1} ", flag, ((Object)(object)_confettiTemplateRoot != (Object)null) ? ((Object)_confettiTemplateRoot).name : "null") + "ps=" + (((Object)(object)_confettiTemplate != (Object)null) ? ((Object)_confettiTemplate).name : "null")); if (!flag) { instance?.LogAlways("[BlindDeafMute] Deaf bonus confetti SKIPPED — no cached ParticleSystem. Visit Airport (or any scene with a BasketballHoop) once so it can be cached, then try again."); } else if ((Object)(object)instance != (Object)null) { ((MonoBehaviour)instance).StartCoroutine(PlayConfettiRoutine(worldPos)); } else { PlayConfettiImmediate(worldPos); } } private static IEnumerator PlayConfettiRoutine(Vector3 worldPos) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) BlindDeafMuteChallengePlugin plugin = BlindDeafMuteChallengePlugin.Instance; GameObject clone; try { bool templateWasActive = _confettiTemplateRoot.activeSelf; _confettiTemplateRoot.SetActive(false); clone = Object.Instantiate(_confettiTemplateRoot); _confettiTemplateRoot.SetActive(templateWasActive); ((Object)clone).name = "BDM_DeafBonusConfetti"; clone.transform.SetParent((Transform)null, true); clone.transform.position = worldPos; clone.transform.rotation = Quaternion.identity; clone.transform.localScale = Vector3.one; clone.SetActive(false); plugin?.LogDebug($"[BlindDeafMute] Confetti clone created id={((Object)clone).GetInstanceID()} " + $"active={clone.activeSelf} pos={clone.transform.position} " + $"psCount={clone.GetComponentsInChildren(true).Length}"); } catch (Exception ex) { Exception ex2 = ex; plugin?.LogAlways("[BlindDeafMute] Deaf bonus confetti clone failed: " + ex2.Message); yield break; } yield return null; try { if ((Object)(object)clone == (Object)null) { plugin?.LogAlways("[BlindDeafMute] Confetti clone was destroyed before play."); yield break; } clone.SetActive(true); ParticleSystem[] systems = clone.GetComponentsInChildren(true); plugin?.LogDebug($"[BlindDeafMute] Confetti activated clone at {clone.transform.position}, systems={systems.Length}"); for (int i = 0; i < systems.Length; i++) { ParticleSystem ps = systems[i]; MainModule main = ps.main; plugin?.LogDebug($"[BlindDeafMute] Confetti PS[{i}] name={((Object)((Component)ps).gameObject).name} " + $"playOnAwake={((MainModule)(ref main)).playOnAwake} isPlaying={ps.isPlaying} " + $"renderer={(Object)(object)((Component)ps).GetComponent() != (Object)null}"); ps.Clear(true); ps.Play(true); plugin?.LogDebug($"[BlindDeafMute] Confetti PS[{i}] after Play isPlaying={ps.isPlaying}"); main = default(MainModule); } if ((Object)(object)_successTemplate != (Object)null) { _successTemplate.Play(); plugin?.LogDebug("[BlindDeafMute] Confetti success SFX Play() called."); } else { plugin?.LogDebug("[BlindDeafMute] Confetti success SFX template is null."); } plugin?.LogAlways($"[BlindDeafMute] Deaf bonus confetti PLAYED at {worldPos} (systems={systems.Length})."); } catch (Exception ex) { Exception ex3 = ex; plugin?.LogAlways("[BlindDeafMute] Deaf bonus confetti play failed: " + ex3.Message); } if ((Object)(object)clone != (Object)null) { Object.Destroy((Object)(object)clone, 6f); } } private static void PlayConfettiImmediate(Vector3 worldPos) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) try { bool activeSelf = _confettiTemplateRoot.activeSelf; _confettiTemplateRoot.SetActive(false); GameObject val = Object.Instantiate(_confettiTemplateRoot, worldPos, Quaternion.identity); _confettiTemplateRoot.SetActive(activeSelf); val.SetActive(true); ParticleSystem[] componentsInChildren = val.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].Clear(true); componentsInChildren[i].Play(true); } Object.Destroy((Object)(object)val, 6f); if ((Object)(object)_successTemplate != (Object)null) { _successTemplate.Play(); } } catch (Exception ex) { BlindDeafMuteChallengePlugin.Instance?.LogAlways("[BlindDeafMute] Deaf bonus confetti failed: " + ex.Message); } } private static void CacheConfettiTemplate(bool forceLog) { if ((Object)(object)_confettiTemplate != (Object)null && (Object)(object)_confettiTemplateRoot != (Object)null) { if (forceLog) { BlindDeafMuteChallengePlugin.Instance?.LogDebug("[BlindDeafMute] Confetti cache HIT root=" + ((Object)_confettiTemplateRoot).name); } return; } _confettiTemplate = null; _confettiTemplateRoot = null; BasketballHoop[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); int num = ((array != null) ? array.Length : 0); BlindDeafMuteChallengePlugin.Instance?.LogDebug($"[BlindDeafMute] Confetti cache MISS — scanning BasketballHoop count={num}"); if (array == null || array.Length == 0) { if (forceLog) { BlindDeafMuteChallengePlugin.Instance?.LogAlways("[BlindDeafMute] Confetti: 0 BasketballHoop in this scene — cannot cache yet."); } return; } for (int i = 0; i < array.Length; i++) { BasketballHoop val = array[i]; if ((Object)(object)val == (Object)null) { continue; } ParticleSystem val2 = val.confetti; string text = "hoop.confetti field"; if ((Object)(object)val2 == (Object)null) { Transform val3 = FindChildNamed(((Component)val).transform, "Confetti"); if ((Object)(object)val3 != (Object)null) { val2 = ((Component)val3).GetComponent() ?? ((Component)val3).GetComponentInChildren(true); text = "child '" + ((Object)val3).name + "'"; } } if ((Object)(object)val2 == (Object)null) { val2 = ((Component)val).GetComponentInChildren(true); text = "GetComponentInChildren"; } BlindDeafMuteChallengePlugin.Instance?.LogDebug($"[BlindDeafMute] Confetti hoop[{i}]='{((Object)val).name}' source={text} " + "ps=" + (((Object)(object)val2 != (Object)null) ? ((Object)((Component)val2).gameObject).name : "null") + " " + $"fieldNull={(Object)(object)val.confetti == (Object)null}"); if (!((Object)(object)val2 == (Object)null)) { try { bool activeSelf = ((Component)val2).gameObject.activeSelf; ((Component)val2).gameObject.SetActive(false); GameObject val4 = Object.Instantiate(((Component)val2).gameObject); ((Component)val2).gameObject.SetActive(activeSelf); ((Object)val4).name = "BDM_ConfettiTemplate"; val4.SetActive(false); Object.DontDestroyOnLoad((Object)(object)val4); _confettiTemplateRoot = val4; _confettiTemplate = val4.GetComponent() ?? val4.GetComponentInChildren(true); _successTemplate = val.success; BlindDeafMuteChallengePlugin.Instance?.LogAlways("[BlindDeafMute] Confetti template CACHED from '" + ((Object)val).name + "' via " + text + " → persistPs=" + (((Object)(object)_confettiTemplate != (Object)null) ? ((Object)_confettiTemplate).name : "null") + "."); return; } catch (Exception ex) { BlindDeafMuteChallengePlugin.Instance?.LogAlways("[BlindDeafMute] Confetti template cache failed: " + ex.Message); } } } if (forceLog) { BlindDeafMuteChallengePlugin.Instance?.LogAlways("[BlindDeafMute] Confetti: found BasketballHoop(s) but no ParticleSystem to cache."); } } private static Transform FindChildNamed(Transform root, string name) { if ((Object)(object)root == (Object)null) { return null; } if (string.Equals(((Object)root).name, name, StringComparison.OrdinalIgnoreCase)) { return root; } for (int i = 0; i < root.childCount; i++) { Transform val = FindChildNamed(root.GetChild(i), name); if ((Object)(object)val != (Object)null) { return val; } } return null; } } internal static class BdmDeafDetection { private struct OutlineEdge { public LineRenderer Line; public Vector3 Anchor; } private const float WidthReferenceDistance = 8f; private const float WidthScaleMin = 0.45f; private const float WidthScaleMax = 18f; private static Coroutine _routine; private static float _cooldownStartedAt = -1f; private static float _useStartedAt = -1f; private static float _useDurationSeconds = 1f; private static GameObject _outlineRoot; private static Material _lineMaterial; private static readonly List _edges = new List(256); internal static bool IsActive => _routine != null; internal static bool IsOnCooldown => CooldownRemainingSeconds > 0f; internal static float CooldownRemainingSeconds { get { if (_cooldownStartedAt < 0f) { return 0f; } float liveCooldownSeconds = GetLiveCooldownSeconds(); return Mathf.Max(0f, _cooldownStartedAt + liveCooldownSeconds - Time.unscaledTime); } } internal static bool IsReady => !IsActive && !IsOnCooldown; internal static float CooldownDurationSeconds => GetLiveCooldownSeconds(); internal static float ActiveRemainingSeconds => (!IsActive) ? 0f : Mathf.Max(0f, _useStartedAt + _useDurationSeconds - Time.unscaledTime); internal static float HudCooldownFill { get { if (!IsOnCooldown && !IsActive) { return 1f; } float cooldownDurationSeconds = CooldownDurationSeconds; if (cooldownDurationSeconds <= 0.01f || _cooldownStartedAt < 0f) { return 1f; } return Mathf.Clamp01(1f - CooldownRemainingSeconds / cooldownDurationSeconds); } } internal static float HudUseFill { get { if (!IsActive || _useDurationSeconds <= 0.01f) { return 0f; } return Mathf.Clamp01(ActiveRemainingSeconds / _useDurationSeconds); } } internal static void TryActivate() { BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; if ((Object)(object)instance == (Object)null) { return; } if (!instance.IsLocalDeafActive) { instance.LogAlways("[BlindDeafMute] Detection is for Deaf players only."); return; } BdmSyncedSettings effectiveSettings = instance.GetEffectiveSettings(); if (!effectiveSettings.EnableDetection) { instance.LogAlways("[BlindDeafMute] Detection power is disabled by host."); return; } if (IsActive) { instance.LogAlways("[BlindDeafMute] Detection already active."); return; } if (IsOnCooldown) { instance.LogAlways($"[BlindDeafMute] Detection on cooldown ({CooldownRemainingSeconds:0}s left)."); return; } float num = Mathf.Clamp(effectiveSettings.DetectionDurationSeconds, 0.5f, 120f); float num2 = Mathf.Clamp(effectiveSettings.DetectionCooldownSeconds, 1f, 3600f); _useDurationSeconds = num; _useStartedAt = Time.unscaledTime; _cooldownStartedAt = Time.unscaledTime; _routine = ((MonoBehaviour)instance).StartCoroutine(RunDetection(num)); instance.LogAlways($"[BlindDeafMute] Detection activated — {num:0.#}s use, cooldown {num2:0}s."); } internal static void Cancel() { BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; if (_routine != null && (Object)(object)instance != (Object)null) { ((MonoBehaviour)instance).StopCoroutine(_routine); _routine = null; } ClearLineRenderers(); } internal static void Shutdown() { Cancel(); _cooldownStartedAt = -1f; if ((Object)(object)_outlineRoot != (Object)null) { Object.Destroy((Object)(object)_outlineRoot); _outlineRoot = null; } if ((Object)(object)_lineMaterial != (Object)null) { Object.Destroy((Object)(object)_lineMaterial); _lineMaterial = null; } } private static float GetLiveCooldownSeconds() { BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; if ((Object)(object)instance == (Object)null) { return 120f; } return Mathf.Clamp(instance.GetEffectiveSettings().DetectionCooldownSeconds, 1f, 3600f); } private static IEnumerator RunDetection(float duration) { BuildOutlines(); float end = Time.unscaledTime + duration; while (Time.unscaledTime < end) { if (Time.frameCount % 30 == 0) { BuildOutlines(); } else { UpdateOutlineWidths(); } yield return null; } ClearLineRenderers(); _routine = null; BlindDeafMuteChallengePlugin.Instance?.LogAlways("[BlindDeafMute] Detection finished."); } private static void BuildOutlines() { //IL_003a: 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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_00c8: 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_00dd: 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_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) EnsureRoot(); ClearLineRenderers(); Color color = (Color)(((Object)(object)BlindDeafMuteChallengePlugin.Instance != (Object)null) ? BlindDeafMuteChallengePlugin.Instance.DetectionOutlineColor : new Color(1f, 0f, 0.988f, 1f)); Camera camera = GetCamera(); Vector3 val = (((Object)(object)camera != (Object)null) ? ((Component)camera).transform.position : Vector3.zero); try { if (Luggage.ALL_LUGGAGE == null) { return; } for (int i = 0; i < Luggage.ALL_LUGGAGE.Count; i++) { Luggage val2 = Luggage.ALL_LUGGAGE[i]; if (!((Object)(object)val2 == (Object)null) && ((Component)val2).gameObject.activeInHierarchy && !(val2 is RespawnChest)) { Bounds luggageBounds = GetLuggageBounds(val2); float num = (((Object)(object)camera != (Object)null) ? Vector3.Distance(val, ((Bounds)(ref luggageBounds)).center) : 8f); float num2 = Mathf.Clamp((num - 12f) * 0.025f, 0f, 4f); ((Bounds)(ref luggageBounds)).Expand(0.15f + num2); AddBoxOutline(luggageBounds, color, ((Bounds)(ref luggageBounds)).center); } } } catch { } UpdateOutlineWidths(); } private static Bounds GetLuggageBounds(Luggage luggage) { //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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: 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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) Renderer[] meshRenderers = luggage.meshRenderers; bool flag = false; Bounds result = default(Bounds); ((Bounds)(ref result))..ctor(((Component)luggage).transform.position, Vector3.one * 0.8f); if (meshRenderers != null) { foreach (Renderer obj in meshRenderers) { MeshRenderer val = (MeshRenderer)(object)((obj is MeshRenderer) ? obj : null); if (!((Object)(object)val == (Object)null) && ((Renderer)val).enabled) { if (!flag) { result = ((Renderer)val).bounds; flag = true; } else { ((Bounds)(ref result)).Encapsulate(((Renderer)val).bounds); } } } } if (!flag) { try { Vector3 val2 = luggage.Center(); result = new Bounds(val2, Vector3.one * 1.2f); } catch { ((Bounds)(ref result))..ctor(((Component)luggage).transform.position, Vector3.one * 1.2f); } } return result; } private static void AddBoxOutline(Bounds bounds, Color color, Vector3 anchor) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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_0028: Unknown result type (might be due to invalid IL or missing references) //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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_009a: 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_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: 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_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00de: 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_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0134: 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) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Expected O, but got Unknown //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) Vector3 center = ((Bounds)(ref bounds)).center; Vector3 extents = ((Bounds)(ref bounds)).extents; Vector3[] array = (Vector3[])(object)new Vector3[8] { center + new Vector3(0f - extents.x, 0f - extents.y, 0f - extents.z), center + new Vector3(0f - extents.x, 0f - extents.y, extents.z), center + new Vector3(0f - extents.x, extents.y, 0f - extents.z), center + new Vector3(0f - extents.x, extents.y, extents.z), center + new Vector3(extents.x, 0f - extents.y, 0f - extents.z), center + new Vector3(extents.x, 0f - extents.y, extents.z), center + new Vector3(extents.x, extents.y, 0f - extents.z), center + new Vector3(extents.x, extents.y, extents.z) }; int[,] array2 = new int[12, 2] { { 0, 1 }, { 0, 2 }, { 0, 4 }, { 7, 3 }, { 7, 5 }, { 7, 6 }, { 1, 3 }, { 1, 5 }, { 2, 3 }, { 2, 6 }, { 4, 5 }, { 4, 6 } }; float num = ComputeWidth(Vector3.Distance(GetCameraPos(), anchor)); for (int i = 0; i < array2.GetLength(0); i++) { GameObject val = new GameObject("Edge"); val.transform.SetParent(_outlineRoot.transform, false); LineRenderer val2 = val.AddComponent(); ((Renderer)val2).sharedMaterial = GetLineMaterial(); val2.positionCount = 2; val2.useWorldSpace = true; val2.widthMultiplier = num; val2.startWidth = num; val2.endWidth = num; val2.startColor = color; val2.endColor = color; ((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)val2).receiveShadows = false; ((Renderer)val2).allowOcclusionWhenDynamic = false; val2.SetPosition(0, array[array2[i, 0]]); val2.SetPosition(1, array[array2[i, 1]]); _edges.Add(new OutlineEdge { Line = val2, Anchor = anchor }); } } private static void UpdateOutlineWidths() { //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_0042: 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) if (_edges.Count == 0) { return; } Vector3 cameraPos = GetCameraPos(); for (int i = 0; i < _edges.Count; i++) { OutlineEdge outlineEdge = _edges[i]; if (!((Object)(object)outlineEdge.Line == (Object)null)) { float distance = Vector3.Distance(cameraPos, outlineEdge.Anchor); float num = ComputeWidth(distance); outlineEdge.Line.widthMultiplier = num; outlineEdge.Line.startWidth = num; outlineEdge.Line.endWidth = num; } } } private static float ComputeWidth(float distance) { BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; float num = (((Object)(object)instance != (Object)null) ? instance.DetectionOutlineThickness : 0.06f); float num2 = Mathf.Clamp(Mathf.Max(distance, 0.5f) / 8f, 0.45f, 18f); return Mathf.Max(0.002f, num * num2); } private static Camera GetCamera() { try { if ((Object)(object)MainCamera.instance != (Object)null && (Object)(object)MainCamera.instance.cam != (Object)null) { return MainCamera.instance.cam; } } catch { } return Camera.main; } private static Vector3 GetCameraPos() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) Camera camera = GetCamera(); if ((Object)(object)camera != (Object)null) { return ((Component)camera).transform.position; } Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter != (Object)null) { try { return localCharacter.Head; } catch { return ((Component)localCharacter).transform.position; } } return Vector3.zero; } private static void EnsureRoot() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown if (!((Object)(object)_outlineRoot != (Object)null)) { _outlineRoot = new GameObject("BDM_DetectionOutlines"); Object.DontDestroyOnLoad((Object)(object)_outlineRoot); } } private static void ClearLineRenderers() { _edges.Clear(); if (!((Object)(object)_outlineRoot == (Object)null)) { for (int num = _outlineRoot.transform.childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)_outlineRoot.transform.GetChild(num)).gameObject); } } } private static Material GetLineMaterial() { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_00ad: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_lineMaterial != (Object)null) { return _lineMaterial; } Shader val = Shader.Find("Hidden/Internal-Colored"); if ((Object)(object)val == (Object)null) { val = Shader.Find("Sprites/Default"); } if ((Object)(object)val == (Object)null) { val = Shader.Find("Unlit/Color"); } _lineMaterial = new Material(val); ((Object)_lineMaterial).hideFlags = (HideFlags)61; _lineMaterial.SetInt("_ZTest", 8); _lineMaterial.SetInt("_ZWrite", 0); if (_lineMaterial.HasProperty("_Color")) { _lineMaterial.SetColor("_Color", Color.white); } return _lineMaterial; } } internal static class BdmEmojiBubbles { private sealed class Bubble { internal GameObject Go; internal RectTransform Rect; internal RawImage Image; internal Character Follow; internal int CharacterId; internal float BornAt; internal float DieAt; internal float Size; internal Coroutine Routine; } private sealed class ReactingCue { internal GameObject Go; internal RectTransform Rect; internal Character Follow; internal int CharacterId; internal Coroutine Routine; } private const float HeadWorldOffsetY = 0.35f; private const float ScreenYBoost = 36f; private const float StringGap = 4f; private const float PopInSeconds = 0.12f; private const float FadeOutSeconds = 0.22f; private static readonly Dictionary> _byCharacter = new Dictionary>(8); private static readonly Dictionary _reacting = new Dictionary(4); private static readonly HashSet _reactingWanted = new HashSet(); private static readonly Dictionary _reactingFollow = new Dictionary(4); private static readonly Dictionary _reactingSenderCue = new Dictionary(4); internal static bool Show(Character character, string codeKey, float durationSeconds) { //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Expected O, but got Unknown //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)character == (Object)null || string.IsNullOrEmpty(codeKey)) { return false; } BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; if ((Object)(object)instance != (Object)null && instance.IsBlindEffectWanted()) { instance.LogDebug("[BlindDeafMute] Emoji bubble skipped — local player is Blind."); return false; } if ((Object)(object)instance != (Object)null && instance.BlockAlphabetEmojis && BdmEmojiCatalog.IsAlphabetCodeKey(codeKey)) { instance.LogDebug("[BlindDeafMute] Alphabet emoji blocked: " + codeKey); return false; } if ((Object)(object)instance != (Object)null && !instance.ShowSkinToneVariants && BdmEmojiCatalog.IsSkinToneVariant(codeKey)) { instance.LogDebug("[BlindDeafMute] Skin-tone emoji blocked: " + codeKey); return false; } GUIManager instance2 = GUIManager.instance; if ((Object)(object)instance2 == (Object)null || (Object)(object)instance2.hudCanvas == (Object)null) { instance?.LogAlways("[BlindDeafMute] Emoji bubble skipped — no HUD canvas."); return false; } BdmEmojiCatalog.EnsureLoaded(); BdmEmojiCatalog.Entry entry = BdmEmojiCatalog.FindByCodeKey(codeKey); Texture2D texture = BdmEmojiCatalog.GetTexture(entry); if ((Object)(object)texture == (Object)null) { instance?.LogAlways("[BlindDeafMute] Emoji bubble missing texture for '" + codeKey + "' (is emojis/ installed?)."); return false; } int instanceID = ((Object)character).GetInstanceID(); float localBubbleSize = GetLocalBubbleSize(instance); float num = Mathf.Max(0.5f, durationSeconds); bool flag = (Object)(object)instance == (Object)null || instance.AllowEmojiString; int num2 = (((Object)(object)instance != (Object)null) ? Mathf.Clamp(instance.MaxEmojiStringLength, 1, 16) : 6); if (!_byCharacter.TryGetValue(instanceID, out var value)) { value = new List(num2); _byCharacter[instanceID] = value; } if (!flag) { ClearGroup(value, restoreReacting: false); } else { while (value.Count >= num2) { DestroyBubble(value[0], value); } } GameObject val = new GameObject("BDM_EmojiBubble", new Type[1] { typeof(RectTransform) }); RectTransform component = val.GetComponent(); ((Transform)component).SetParent(((Component)instance2.hudCanvas).transform, false); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.zero; component.pivot = new Vector2(0.5f, 0.5f); component.sizeDelta = new Vector2(localBubbleSize * 0.7f, localBubbleSize * 0.7f); RawImage val2 = val.AddComponent(); val2.texture = (Texture)(object)texture; ((Graphic)val2).raycastTarget = false; ((Graphic)val2).color = new Color(1f, 1f, 1f, 0f); val.transform.SetAsLastSibling(); float unscaledTime = Time.unscaledTime; Bubble bubble = new Bubble { Go = val, Rect = component, Image = val2, Follow = character, CharacterId = instanceID, BornAt = unscaledTime, DieAt = unscaledTime + num, Size = localBubbleSize }; value.Add(bubble); HideReactingCue(instanceID); for (int i = 0; i < value.Count; i++) { value[i].DieAt = bubble.DieAt; } PositionGroup(value, flag); MonoBehaviour val3 = (MonoBehaviour)(object)instance; if ((Object)(object)val3 != (Object)null) { bubble.Routine = val3.StartCoroutine(RunBubble(bubble)); } else { Object.Destroy((Object)(object)val, num); } instance?.LogDebug("[BlindDeafMute] Emoji bubble shown '" + codeKey + "' on " + character.characterName + "."); return true; } internal static void ClearForCharacter(Character character) { if (!((Object)(object)character == (Object)null)) { int instanceID = ((Object)character).GetInstanceID(); if (!_byCharacter.TryGetValue(instanceID, out var value)) { TryRestoreReacting(instanceID); return; } ClearGroup(value, restoreReacting: true); _byCharacter.Remove(instanceID); } } internal static void SetReacting(Character character, bool reacting, string senderCueKey = null) { if ((Object)(object)character == (Object)null) { return; } BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; int instanceID = ((Object)character).GetInstanceID(); if ((Object)(object)instance != (Object)null && (instance.IsBlindEffectWanted() || !instance.ShowReactingCue)) { ClearReactingWanted(instanceID); HideReactingCue(instanceID); return; } if (!reacting) { ClearReactingWanted(instanceID); HideReactingCue(instanceID); return; } string text = BlindDeafMuteChallengePlugin.NormalizeIncomingCueAsset((!string.IsNullOrEmpty(senderCueKey)) ? senderCueKey : (((Object)(object)instance != (Object)null) ? instance.IncomingEmojiCueKey : "1f4ac")); _reactingWanted.Add(instanceID); _reactingFollow[instanceID] = character; _reactingSenderCue[instanceID] = text; if (HasActiveBubbles(instanceID)) { HideReactingCue(instanceID); } else { ShowReactingCue(character, text); } } private static void ClearReactingWanted(int characterId) { _reactingWanted.Remove(characterId); _reactingFollow.Remove(characterId); _reactingSenderCue.Remove(characterId); } private static bool HasActiveBubbles(int characterId) { List value; return _byCharacter.TryGetValue(characterId, out value) && value.Count > 0; } private static void ShowReactingCue(Character character, string senderCueKey) { //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Expected O, but got Unknown //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Expected O, but got Unknown //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0217: 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) if ((Object)(object)character == (Object)null) { return; } int instanceID = ((Object)character).GetInstanceID(); if (_reacting.ContainsKey(instanceID)) { return; } BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; GUIManager instance2 = GUIManager.instance; if (!((Object)(object)instance2 == (Object)null) && !((Object)(object)instance2.hudCanvas == (Object)null)) { BdmEmojiCatalog.EnsureLoaded(); string text = (((Object)(object)instance != (Object)null) ? instance.ResolveIncomingCueDisplayKey(senderCueKey) : BlindDeafMuteChallengePlugin.NormalizeIncomingCueAsset(senderCueKey)); Texture2D texture = BdmEmojiCatalog.GetTexture(BdmEmojiCatalog.FindByCodeKey(text)); if ((Object)(object)texture == (Object)null && text != "1f4ac") { texture = BdmEmojiCatalog.GetTexture(BdmEmojiCatalog.FindByCodeKey("1f4ac")); } GameObject val = new GameObject("BDM_EmojiReacting", new Type[1] { typeof(RectTransform) }); RectTransform component = val.GetComponent(); ((Transform)component).SetParent(((Component)instance2.hudCanvas).transform, false); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.zero; component.pivot = new Vector2(0.5f, 0.5f); float num = GetLocalBubbleSize(instance) * 0.5f; component.sizeDelta = new Vector2(num, num); RawImage val2 = val.AddComponent(); ((Graphic)val2).raycastTarget = false; if ((Object)(object)texture != (Object)null) { val2.texture = (Texture)(object)texture; ((Graphic)val2).color = Color.white; } else { Texture2D val3 = new Texture2D(2, 2, (TextureFormat)4, false); val3.SetPixels((Color[])(object)new Color[4] { Color.white, Color.white, Color.white, Color.white }); val3.Apply(false, true); val2.texture = (Texture)(object)val3; ((Graphic)val2).color = new Color(0.95f, 0.95f, 0.95f, 0.9f); component.sizeDelta = new Vector2(num * 1.2f, num * 0.7f); } ReactingCue reactingCue = new ReactingCue { Go = val, Rect = component, Follow = character, CharacterId = instanceID }; _reacting[instanceID] = reactingCue; if ((Object)(object)instance != (Object)null) { reactingCue.Routine = ((MonoBehaviour)instance).StartCoroutine(RunReacting(reactingCue)); } } } private static void HideReactingCue(int characterId) { if (_reacting.TryGetValue(characterId, out var value)) { _reacting.Remove(characterId); if (value.Routine != null && (Object)(object)BlindDeafMuteChallengePlugin.Instance != (Object)null) { ((MonoBehaviour)BlindDeafMuteChallengePlugin.Instance).StopCoroutine(value.Routine); } if ((Object)(object)value.Go != (Object)null) { Object.Destroy((Object)(object)value.Go); } } } private static void TryRestoreReacting(int characterId) { if (_reactingWanted.Contains(characterId) && !HasActiveBubbles(characterId) && _reactingFollow.TryGetValue(characterId, out var value) && !((Object)(object)value == (Object)null)) { string value2; string senderCueKey = (_reactingSenderCue.TryGetValue(characterId, out value2) ? value2 : "1f4ac"); ShowReactingCue(value, senderCueKey); } } private static float GetLocalBubbleSize(BlindDeafMuteChallengePlugin plugin) { float num = (((Object)(object)plugin != (Object)null) ? Mathf.Clamp(plugin.EmojiBubbleSize, 24f, 256f) : 72f); return num * BdmEmojiCatalog.UiScale; } private static IEnumerator RunBubble(Bubble bubble) { while ((Object)(object)bubble.Go != (Object)null && Time.unscaledTime < bubble.DieAt) { float now = Time.unscaledTime; float age = now - bubble.BornAt; float left = bubble.DieAt - now; float popT = Mathf.Clamp01(age / 0.12f); float scale = Mathf.Lerp(0.7f, 1f, popT); float alpha = popT; if (left < 0.22f) { alpha *= Mathf.Clamp01(left / 0.22f); } if ((Object)(object)bubble.Rect != (Object)null) { bubble.Rect.sizeDelta = new Vector2(bubble.Size * scale, bubble.Size * scale); } if ((Object)(object)bubble.Image != (Object)null) { Color c = ((Graphic)bubble.Image).color; c.a = alpha; ((Graphic)bubble.Image).color = c; } if (_byCharacter.TryGetValue(bubble.CharacterId, out var group)) { PositionGroup(stringMode: (Object)(object)BlindDeafMuteChallengePlugin.Instance == (Object)null || BlindDeafMuteChallengePlugin.Instance.AllowEmojiString, group: group); } yield return null; group = null; } if (_byCharacter.TryGetValue(bubble.CharacterId, out var g)) { int characterId = bubble.CharacterId; DestroyBubble(bubble, g); if (g.Count == 0) { _byCharacter.Remove(characterId); TryRestoreReacting(characterId); } else { PositionGroup(stringMode: (Object)(object)BlindDeafMuteChallengePlugin.Instance == (Object)null || BlindDeafMuteChallengePlugin.Instance.AllowEmojiString, group: g); } } else if ((Object)(object)bubble.Go != (Object)null) { Object.Destroy((Object)(object)bubble.Go); TryRestoreReacting(bubble.CharacterId); } } private static IEnumerator RunReacting(ReactingCue cue) { while ((Object)(object)cue.Go != (Object)null) { PositionReacting(cue); yield return null; } } private static void ClearGroup(List group, bool restoreReacting) { int num = ((group != null && group.Count > 0) ? group[0].CharacterId : 0); for (int num2 = group.Count - 1; num2 >= 0; num2--) { DestroyBubble(group[num2], group); } if (restoreReacting && num != 0) { TryRestoreReacting(num); } } private static void DestroyBubble(Bubble bubble, List group) { if (bubble != null) { if (bubble.Routine != null && (Object)(object)BlindDeafMuteChallengePlugin.Instance != (Object)null) { ((MonoBehaviour)BlindDeafMuteChallengePlugin.Instance).StopCoroutine(bubble.Routine); bubble.Routine = null; } if ((Object)(object)bubble.Go != (Object)null) { Object.Destroy((Object)(object)bubble.Go); } group.Remove(bubble); } } private static bool TryGetHeadScreen(Character follow, out Vector3 screen) { //IL_0002: 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_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) screen = default(Vector3); if ((Object)(object)follow == (Object)null) { return false; } if (!IsWithinViewDistance(follow)) { return false; } Camera val = null; try { if ((Object)(object)MainCamera.instance != (Object)null && (Object)(object)MainCamera.instance.cam != (Object)null) { val = MainCamera.instance.cam; } } catch { } if ((Object)(object)val == (Object)null) { val = Camera.main; } if ((Object)(object)val == (Object)null) { return false; } Vector3 val2; try { val2 = follow.Head; } catch { val2 = ((Component)follow).transform.position; } val2.y += 0.35f; screen = val.WorldToScreenPoint(val2); if (screen.z < 0.1f) { return false; } screen.y += 36f; return true; } private static bool IsWithinViewDistance(Character follow) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: 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_013a: 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_0140: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0132: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; float num = (((Object)(object)instance != (Object)null) ? instance.EmojiViewDistance : 8f); if (num <= 0f) { return true; } Vector3 val; try { val = follow.Head; } catch { val = ((Component)follow).transform.position; } Character localCharacter = Character.localCharacter; Vector3 val2; if ((Object)(object)localCharacter != (Object)null && (Object)(object)localCharacter != (Object)(object)follow) { try { val2 = localCharacter.Head; } catch { val2 = ((Component)localCharacter).transform.position; } } else { if ((Object)(object)localCharacter != (Object)null && (Object)(object)localCharacter == (Object)(object)follow) { return true; } Camera val3 = null; try { if ((Object)(object)MainCamera.instance != (Object)null && (Object)(object)MainCamera.instance.cam != (Object)null) { val3 = MainCamera.instance.cam; } } catch { } if ((Object)(object)val3 == (Object)null) { val3 = Camera.main; } if ((Object)(object)val3 == (Object)null) { return true; } val2 = ((Component)val3).transform.position; } float num2 = num * num; Vector3 val4 = val - val2; return ((Vector3)(ref val4)).sqrMagnitude <= num2; } private static void PositionGroup(List group, bool stringMode) { //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) if (group == null || group.Count == 0) { return; } Character follow = group[0].Follow; if (!TryGetHeadScreen(follow, out var screen)) { for (int i = 0; i < group.Count; i++) { if ((Object)(object)group[i].Go != (Object)null && group[i].Go.activeSelf) { group[i].Go.SetActive(false); } } return; } float size = group[0].Size; if (!stringMode) { for (int j = 0; j < group.Count; j++) { Bubble bubble = group[j]; if (!((Object)(object)bubble.Go == (Object)null) && !((Object)(object)bubble.Rect == (Object)null)) { if (!bubble.Go.activeSelf) { bubble.Go.SetActive(true); } ((Transform)bubble.Rect).position = screen; } } return; } float num = (float)group.Count * size + (float)(group.Count - 1) * 4f; float num2 = screen.x - num * 0.5f + size * 0.5f; for (int k = 0; k < group.Count; k++) { Bubble bubble2 = group[k]; if (!((Object)(object)bubble2.Go == (Object)null) && !((Object)(object)bubble2.Rect == (Object)null)) { if (!bubble2.Go.activeSelf) { bubble2.Go.SetActive(true); } ((Transform)bubble2.Rect).position = new Vector3(num2 + (float)k * (size + 4f), screen.y, screen.z); } } } private static void PositionReacting(ReactingCue cue) { //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) if (cue == null || (Object)(object)cue.Rect == (Object)null) { return; } if (!TryGetHeadScreen(cue.Follow, out var screen)) { if ((Object)(object)cue.Go != (Object)null && cue.Go.activeSelf) { cue.Go.SetActive(false); } return; } if ((Object)(object)cue.Go != (Object)null && !cue.Go.activeSelf) { cue.Go.SetActive(true); } float num = GetLocalBubbleSize(BlindDeafMuteChallengePlugin.Instance) * 0.85f; ((Transform)cue.Rect).position = new Vector3(screen.x, screen.y + num, screen.z); } } internal static class BdmEmojiCatalog { internal sealed class Entry { internal string FileName; internal string FullPath; internal string CodeKey; internal string SearchBlob; internal string PrimaryShortcode; internal BdmEmojiCategory Category; internal Texture2D Texture; } private static readonly List _all = new List(512); private static readonly Dictionary _byCodeKey = new Dictionary(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary _shortcodes = new Dictionary(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary _codeToShortcode = new Dictionary(StringComparer.OrdinalIgnoreCase); private static bool _loaded; private static bool _preloadStarted; private static bool _preloadDone; private static int _preloadIndex; private static string _folderPath = string.Empty; private static string _status = "not loaded"; private static MethodInfo _loadImageMethod; internal static bool IsPreloadDone => _preloadDone; internal static int PreloadLoadedCount => _preloadIndex; internal static string Status => _status; internal static int Count => _all.Count; internal static float UiScale { get { float num = Mathf.Min((float)Screen.width / 1920f, (float)Screen.height / 1080f); return Mathf.Clamp(num, 0.65f, 1.6f); } } internal static void EnsureLoaded() { if (_loaded) { return; } _loaded = true; _all.Clear(); _byCodeKey.Clear(); _shortcodes.Clear(); _codeToShortcode.Clear(); try { string text = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? string.Empty; _folderPath = Path.Combine(text, "emojis"); EnsureEmojisExtractedFromZip(text, _folderPath); LoadOptionalShortcodeFile(Path.Combine(text, "shortcodes.txt")); LoadOptionalShortcodeFile(Path.Combine(text, "shortcodes", "shortcodes.txt")); LoadOptionalShortcodeFile(Path.Combine(_folderPath, "shortcodes.txt")); SeedBuiltInShortcodes(); if (!Directory.Exists(_folderPath)) { _status = "missing folder: " + _folderPath; BlindDeafMuteChallengePlugin.Instance?.LogAlways("[BlindDeafMute] Emoji folder not found: " + _folderPath); return; } string[] files = Directory.GetFiles(_folderPath, "*.png", SearchOption.TopDirectoryOnly); Array.Sort(files, (IComparer?)StringComparer.OrdinalIgnoreCase); Dictionary> dictionary = new Dictionary>(StringComparer.OrdinalIgnoreCase); foreach (KeyValuePair shortcode in _shortcodes) { string key = NormalizeCodeKey(shortcode.Value); if (!dictionary.TryGetValue(key, out var value)) { value = (dictionary[key] = new List(4)); } value.Add(shortcode.Key); string text2 = shortcode.Key.Replace('_', ' '); if (!string.Equals(text2, shortcode.Key, StringComparison.Ordinal) && !value.Contains(text2)) { value.Add(text2); } } foreach (string text3 in files) { string fileName = Path.GetFileName(text3); string text4 = ParseCodeKey(fileName); if (!string.IsNullOrEmpty(text4)) { string text5 = NormalizeCodeKey(text4); dictionary.TryGetValue(text5, out var value2); if (value2 == null && !string.Equals(text5, text4, StringComparison.OrdinalIgnoreCase)) { dictionary.TryGetValue(text4, out value2); } Entry entry = new Entry { FileName = fileName, FullPath = text3, CodeKey = text4, SearchBlob = BuildSearchBlob(text4, fileName, value2), PrimaryShortcode = GetPrimaryShortcode(text5), Category = BdmEmojiCategoryUtil.ClassifyCodeKey(text4) }; if (string.IsNullOrEmpty(entry.PrimaryShortcode) || string.Equals(entry.PrimaryShortcode, text5, StringComparison.OrdinalIgnoreCase)) { entry.PrimaryShortcode = GetPrimaryShortcode(text4); } _all.Add(entry); RegisterCodeKey(text4, entry); if (!string.Equals(text5, text4, StringComparison.OrdinalIgnoreCase)) { RegisterCodeKey(text5, entry); } } } BlindDeafMuteChallengePlugin.Instance?.LogAlways($"[BlindDeafMute] Shortcodes loaded: {_shortcodes.Count} alias(es)."); _status = $"{_all.Count} png(s) in {_folderPath}"; BlindDeafMuteChallengePlugin.Instance?.LogAlways("[BlindDeafMute] Emoji catalog cached: " + _status); } catch (Exception ex) { _status = "load failed: " + ex.Message; BlindDeafMuteChallengePlugin.Instance?.LogAlways("[BlindDeafMute] Emoji catalog failed: " + ex.Message); } } private static void RegisterCodeKey(string codeKey, Entry entry) { if (!string.IsNullOrEmpty(codeKey) && entry != null && !_byCodeKey.ContainsKey(codeKey)) { _byCodeKey[codeKey] = entry; } } private static void EnsureEmojisExtractedFromZip(string asmDir, string folderPath) { string text = Path.Combine(asmDir, "emojis.zip"); if (!File.Exists(text)) { return; } string path = Path.Combine(folderPath, ".bdm_zip_stamp"); string text2 = BuildZipStamp(text); try { int num = 0; if (Directory.Exists(folderPath)) { num = Directory.GetFiles(folderPath, "*.png", SearchOption.TopDirectoryOnly).Length; } bool flag = File.Exists(path) && string.Equals(File.ReadAllText(path).Trim(), text2, StringComparison.Ordinal); if (num > 0 && flag) { return; } BlindDeafMuteChallengePlugin.Instance?.LogAlways((num > 0) ? "[BlindDeafMute] emojis.zip changed — re-extracting emoji pack..." : "[BlindDeafMute] Extracting emojis.zip next to plugin DLL..."); Directory.CreateDirectory(folderPath); string[] files = Directory.GetFiles(folderPath, "*.png", SearchOption.TopDirectoryOnly); for (int i = 0; i < files.Length; i++) { try { File.Delete(files[i]); } catch { } } int num2 = 0; ZipArchive val = ZipFile.OpenRead(text); try { foreach (ZipArchiveEntry entry in val.Entries) { if (!string.IsNullOrEmpty(entry.Name)) { string fileName = Path.GetFileName(entry.FullName.Replace('\\', '/')); if (!string.IsNullOrEmpty(fileName) && fileName.EndsWith(".png", StringComparison.OrdinalIgnoreCase)) { string destinationFileName = Path.Combine(folderPath, fileName); entry.ExtractToFile(destinationFileName, overwrite: true); num2++; } } } } finally { ((IDisposable)val)?.Dispose(); } File.WriteAllText(path, text2); BlindDeafMuteChallengePlugin.Instance?.LogAlways($"[BlindDeafMute] Extracted {num2} emoji png(s) from emojis.zip."); } catch (Exception ex) { BlindDeafMuteChallengePlugin.Instance?.LogAlways("[BlindDeafMute] Failed extracting emojis.zip: " + ex.Message); } } private static string BuildZipStamp(string zipPath) { FileInfo fileInfo = new FileInfo(zipPath); return fileInfo.Length.ToString(CultureInfo.InvariantCulture) + "|" + fileInfo.LastWriteTimeUtc.Ticks.ToString(CultureInfo.InvariantCulture); } internal static void Filter(string query, List results, bool excludeAlphabet, bool excludeSkinTones, BdmEmojiCategory categoryMask) { EnsureLoaded(); results.Clear(); if (_all.Count == 0) { return; } string text = (query ?? string.Empty).Trim().ToLowerInvariant(); if (text.StartsWith(":")) { text = text.Substring(1); } if (text.EndsWith(":")) { text = text.Substring(0, text.Length - 1); } text = text.Replace('-', ' '); bool flag = !string.IsNullOrEmpty(text); BdmEmojiCategory effectiveMask = (flag ? BdmEmojiCategory.All : categoryMask); if (effectiveMask == BdmEmojiCategory.None && !flag) { return; } if (!flag) { for (int i = 0; i < _all.Count; i++) { Entry entry = _all[i]; if (!ShouldExclude(entry, excludeAlphabet, excludeSkinTones, effectiveMask)) { results.Add(entry); } } return; } string text2 = text.Replace(" ", string.Empty); string text3 = text.Replace(' ', '_'); string[] tokens = text.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries); HashSet seen = new HashSet(); TryAdd(ResolveShortcode(text)); if (!string.Equals(text3, text, StringComparison.Ordinal)) { TryAdd(ResolveShortcode(text3)); } if (!string.Equals(text2, text, StringComparison.Ordinal) && !string.Equals(text2, text3, StringComparison.Ordinal)) { TryAdd(ResolveShortcode(text2)); } foreach (KeyValuePair shortcode in _shortcodes) { string key = shortcode.Key; if (ShortcodeKeyMatches(key, text, text3, text2, tokens)) { TryAdd(FindByCodeKey(shortcode.Value)); } } for (int j = 0; j < _all.Count; j++) { Entry entry2 = _all[j]; if (!ShouldExclude(entry2, excludeAlphabet, excludeSkinTones, effectiveMask) && SearchBlobMatches(entry2.SearchBlob, text, text3, text2, tokens)) { TryAdd(entry2); } } void TryAdd(Entry e) { if (e != null && !ShouldExclude(e, excludeAlphabet, excludeSkinTones, effectiveMask) && seen.Add(e)) { results.Add(e); } } } private static Entry ResolveShortcode(string name) { if (string.IsNullOrEmpty(name)) { return null; } if (!_shortcodes.TryGetValue(name, out var value)) { return null; } return FindByCodeKey(value); } private static bool ShortcodeKeyMatches(string key, string q, string qSnake, string qCompact, string[] tokens) { if (key.IndexOf(q, StringComparison.Ordinal) >= 0 || key.IndexOf(qSnake, StringComparison.Ordinal) >= 0 || key.Replace("_", string.Empty).IndexOf(qCompact, StringComparison.Ordinal) >= 0) { return true; } if (tokens == null || tokens.Length <= 1) { return false; } string text = key.Replace('_', ' '); for (int i = 0; i < tokens.Length; i++) { if (text.IndexOf(tokens[i], StringComparison.Ordinal) < 0 && key.IndexOf(tokens[i], StringComparison.Ordinal) < 0) { return false; } } return true; } private static bool SearchBlobMatches(string blob, string q, string qSnake, string qCompact, string[] tokens) { if (string.IsNullOrEmpty(blob)) { return false; } if (blob.IndexOf(q, StringComparison.Ordinal) >= 0 || blob.IndexOf(qSnake, StringComparison.Ordinal) >= 0 || blob.Replace("_", string.Empty).IndexOf(qCompact, StringComparison.Ordinal) >= 0) { return true; } if (tokens == null || tokens.Length <= 1) { return false; } for (int i = 0; i < tokens.Length; i++) { if (blob.IndexOf(tokens[i], StringComparison.Ordinal) < 0) { return false; } } return true; } private static bool ShouldExclude(Entry e, bool excludeAlphabet, bool excludeSkinTones, BdmEmojiCategory categoryMask) { if (e == null) { return true; } if (excludeAlphabet && IsAlphabetCodeKey(e.CodeKey)) { return true; } if (excludeSkinTones && IsSkinToneVariant(e.CodeKey)) { return true; } if (categoryMask != BdmEmojiCategory.All && (e.Category & categoryMask) == 0) { return true; } return false; } internal static bool IsSkinToneVariant(string codeKey) { if (string.IsNullOrEmpty(codeKey)) { return false; } string[] array = codeKey.Split(new char[1] { '_' }); for (int i = 0; i < array.Length; i++) { if (array[i] == "1f3fb" || array[i] == "1f3fc" || array[i] == "1f3fd" || array[i] == "1f3fe" || array[i] == "1f3ff") { return true; } } return false; } internal static string GetPrimaryShortcode(string codeKey) { if (string.IsNullOrEmpty(codeKey)) { return string.Empty; } if (_codeToShortcode.TryGetValue(codeKey, out var value)) { return value; } string text = NormalizeCodeKey(codeKey); if (!string.Equals(text, codeKey, StringComparison.OrdinalIgnoreCase) && _codeToShortcode.TryGetValue(text, out value)) { return value; } return codeKey; } internal static bool IsAlphabetCodeKey(string codeKey) { if (string.IsNullOrEmpty(codeKey)) { return false; } string[] array = codeKey.Split(new char[1] { '_' }); if (array.Length != 1) { return false; } if (!uint.TryParse(array[0], NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var result)) { return false; } if (result >= 127462 && result <= 127487) { return true; } if (result >= 127280 && result <= 127311) { return true; } if (result >= 127344 && result <= 127373) { return true; } return false; } internal static Entry FindByCodeKey(string codeKey) { EnsureLoaded(); if (string.IsNullOrEmpty(codeKey)) { return null; } if (_byCodeKey.TryGetValue(codeKey, out var value)) { return value; } string text = NormalizeCodeKey(codeKey); if (!string.Equals(text, codeKey, StringComparison.OrdinalIgnoreCase) && _byCodeKey.TryGetValue(text, out value)) { return value; } return null; } internal static string NormalizeCodeKey(string codeKey) { if (string.IsNullOrEmpty(codeKey)) { return string.Empty; } string[] array = codeKey.ToLowerInvariant().Split(new char[1] { '_' }); List list = new List(array.Length); for (int i = 0; i < array.Length; i++) { if (!(array[i] == "fe0f") && array[i].Length != 0) { list.Add(array[i]); } } return (list.Count == 0) ? codeKey.ToLowerInvariant() : string.Join("_", list); } internal static Texture2D PeekTexture(Entry entry) { return entry?.Texture; } internal static Texture2D GetTexture(Entry entry) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown if (entry == null) { return null; } if ((Object)(object)entry.Texture != (Object)null) { return entry.Texture; } try { byte[] bytes = File.ReadAllBytes(entry.FullPath); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); if (!TryLoadImage(val, bytes)) { Object.Destroy((Object)(object)val); return null; } ((Object)val).name = entry.FileName; ((Texture)val).filterMode = (FilterMode)1; ((Texture)val).wrapMode = (TextureWrapMode)1; entry.Texture = val; return val; } catch { return null; } } internal static IEnumerator PreloadAllTexturesCoroutine(int perFrame = 10) { EnsureLoaded(); if (_preloadStarted) { yield break; } _preloadStarted = true; _preloadDone = false; _preloadIndex = 0; perFrame = Mathf.Clamp(perFrame, 2, 32); BlindDeafMuteChallengePlugin.Instance?.LogAlways($"[BlindDeafMute] Emoji texture preload started ({_all.Count} pngs)..."); while (_preloadIndex < _all.Count) { int end = Math.Min(_all.Count, _preloadIndex + perFrame); for (int i = _preloadIndex; i < end; i++) { GetTexture(_all[i]); } _preloadIndex = end; yield return null; } _preloadDone = true; BlindDeafMuteChallengePlugin.Instance?.LogAlways($"[BlindDeafMute] Emoji texture preload done ({_all.Count})."); } private static bool TryLoadImage(Texture2D tex, byte[] bytes) { if (_loadImageMethod == null) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { Type type = assembly.GetType("UnityEngine.ImageConversion"); if (!(type == null)) { _loadImageMethod = type.GetMethod("LoadImage", BindingFlags.Static | BindingFlags.Public, null, new Type[3] { typeof(Texture2D), typeof(byte[]), typeof(bool) }, null); if (_loadImageMethod == null) { _loadImageMethod = type.GetMethod("LoadImage", BindingFlags.Static | BindingFlags.Public, null, new Type[2] { typeof(Texture2D), typeof(byte[]) }, null); } if (_loadImageMethod != null) { break; } } } } if (_loadImageMethod == null) { return false; } object obj = ((_loadImageMethod.GetParameters().Length == 3) ? _loadImageMethod.Invoke(null, new object[3] { tex, bytes, true }) : _loadImageMethod.Invoke(null, new object[2] { tex, bytes })); bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } private static string ParseCodeKey(string fileName) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileName); if (string.IsNullOrEmpty(fileNameWithoutExtension)) { return null; } if (fileNameWithoutExtension.StartsWith("emoji_u", StringComparison.OrdinalIgnoreCase)) { return fileNameWithoutExtension.Substring("emoji_u".Length).ToLowerInvariant(); } if (fileNameWithoutExtension.StartsWith("emoji-", StringComparison.OrdinalIgnoreCase)) { return fileNameWithoutExtension.Substring("emoji-".Length).Replace('-', '_').ToLowerInvariant(); } return fileNameWithoutExtension.ToLowerInvariant(); } private static string BuildSearchBlob(string codeKey, string fileName, List aliases) { StringBuilder stringBuilder = new StringBuilder(96); stringBuilder.Append(codeKey); string text = NormalizeCodeKey(codeKey); if (!string.Equals(text, codeKey, StringComparison.OrdinalIgnoreCase)) { stringBuilder.Append(' '); stringBuilder.Append(text); } stringBuilder.Append(' '); stringBuilder.Append(fileName.ToLowerInvariant()); if (aliases != null) { for (int i = 0; i < aliases.Count; i++) { stringBuilder.Append(' '); stringBuilder.Append(aliases[i]); } } return stringBuilder.ToString(); } private static void LoadOptionalShortcodeFile(string path) { if (!File.Exists(path)) { return; } try { int num = 0; string[] array = File.ReadAllLines(path); foreach (string text in array) { string text2 = text.Trim(); if (text2.Length == 0 || text2.StartsWith("#")) { continue; } int num2 = text2.IndexOf('='); if (num2 <= 0) { continue; } string text3 = text2.Substring(0, num2).Trim().Trim(new char[1] { ':' }) .ToLowerInvariant(); string text4 = text2.Substring(num2 + 1).Trim().ToLowerInvariant(); if (text4.StartsWith("emoji_u", StringComparison.OrdinalIgnoreCase)) { text4 = text4.Substring("emoji_u".Length); } text4 = text4.Replace('-', '_'); text4 = NormalizeCodeKey(text4); if (text3.Length != 0 && text4.Length != 0) { if (!_shortcodes.ContainsKey(text3)) { num++; } _shortcodes[text3] = text4; if (!_codeToShortcode.ContainsKey(text4)) { _codeToShortcode[text4] = text3; } } } BlindDeafMuteChallengePlugin.Instance?.LogAlways($"[BlindDeafMute] Loaded shortcodes from {path} (+{num} new, {_shortcodes.Count} total)."); } catch (Exception ex) { BlindDeafMuteChallengePlugin.Instance?.LogAlways("[BlindDeafMute] Failed reading shortcodes.txt: " + ex.Message); } } private static void SeedBuiltInShortcodes() { A("copyright", "00a9"); A("registered", "00ae"); A("eyes", "1f440"); A("eye", "1f441"); A("tongue", "1f445"); A("wave", "1f44b"); A("ok_hand", "1f44c"); A("thumbsup", "1f44d"); A("+1", "1f44d"); A("thumbsdown", "1f44e"); A("-1", "1f44e"); A("clap", "1f44f"); A("open_hands", "1f450"); A("crown", "1f451"); A("point_left", "1f448"); A("point_right", "1f449"); A("point_up_2", "1f446"); A("point_down", "1f447"); A("point_up", "261d"); A("index_pointing", "1faf5"); A("you", "1faf5"); A("raised_hand", "270b"); A("vulcan", "1f596"); A("fingers_crossed", "1f91e"); A("love_you", "1f91f"); A("call_me", "1f919"); A("muscle", "1f4aa"); A("pray", "1f64f"); A("handshake", "1f91d"); A("writing_hand", "270d"); A("heart", "2764"); A("yellow_heart", "1f49b"); A("green_heart", "1f49a"); A("blue_heart", "1f499"); A("purple_heart", "1f49c"); A("black_heart", "1f5a4"); A("broken_heart", "1f494"); A("two_hearts", "1f495"); A("sparkles", "2728"); A("star", "2b50"); A("fire", "1f525"); A("100", "1f4af"); A("boom", "1f4a5"); A("anger", "1f4a2"); A("sweat_drops", "1f4a6"); A("dash", "1f4a8"); A("zzz", "1f4a4"); A("speech_balloon", "1f4ac"); A("thought_balloon", "1f4ad"); A("hole", "1f573"); A("sos", "1f198"); A("exclamation", "2757"); A("question", "2753"); A("grimacing", "1f62c"); A("grin", "1f601"); A("grinning", "1f600"); A("smiley", "1f603"); A("smile", "1f604"); A("sweat_smile", "1f605"); A("laughing", "1f606"); A("joy", "1f602"); A("rofl", "1f923"); A("innocent", "1f607"); A("wink", "1f609"); A("blush", "1f60a"); A("slight_smile", "1f642"); A("upside_down", "1f643"); A("yum", "1f60b"); A("relieved", "1f60c"); A("heart_eyes", "1f60d"); A("kissing_heart", "1f618"); A("kissing", "1f617"); A("stuck_out_tongue", "1f61b"); A("stuck_out_tongue_wink", "1f61c"); A("stuck_out_tongue_closed", "1f61d"); A("money_mouth", "1f911"); A("hugs", "1f917"); A("thinking", "1f914"); A("shush", "1f92b"); A("zipper_mouth", "1f910"); A("raised_eyebrow", "1f928"); A("neutral", "1f610"); A("expressionless", "1f611"); A("no_mouth", "1f636"); A("smirk", "1f60f"); A("unamused", "1f612"); A("roll_eyes", "1f644"); A("lying", "1f925"); A("pensive", "1f614"); A("sleepy", "1f62a"); A("drool", "1f924"); A("sleeping", "1f634"); A("mask", "1f637"); A("face_with_thermometer", "1f912"); A("injured", "1f915"); A("nauseated", "1f922"); A("sick", "1f922"); A("vomit", "1f92e"); A("sneeze", "1f927"); A("hot", "1f975"); A("cold_face", "1f976"); A("woozy", "1f974"); A("dizzy", "1f635"); A("exploding_head", "1f92f"); A("cowboy", "1f920"); A("party", "1f973"); A("sunglasses", "1f60e"); A("nerd", "1f913"); A("monocle", "1f9d0"); A("confused", "1f615"); A("worried", "1f61f"); A("slight_frown", "1f641"); A("open_mouth", "1f62e"); A("hushed", "1f62f"); A("astonished", "1f632"); A("flushed", "1f633"); A("pleading", "1f97a"); A("frowning", "1f626"); A("anguished", "1f627"); A("fearful", "1f628"); A("cold_sweat", "1f630"); A("disappointed_relieved", "1f625"); A("cry", "1f622"); A("sob", "1f62d"); A("scream", "1f631"); A("confounded", "1f616"); A("persevere", "1f623"); A("disappointed", "1f61e"); A("sweat", "1f613"); A("weary", "1f629"); A("tired", "1f62b"); A("yawn", "1f971"); A("triumph", "1f624"); A("rage", "1f621"); A("angry", "1f620"); A("cursing", "1f92c"); A("smiling_imp", "1f608"); A("imp", "1f47f"); A("skull", "1f480"); A("ghost", "1f47b"); A("alien", "1f47d"); A("robot", "1f916"); A("poop", "1f4a9"); A("clown", "1f921"); A("check", "2705"); A("x", "274c"); A("warning", "26a0"); A("arrow_up", "2b06"); A("arrow_down", "2b07"); A("arrow_left", "2b05"); A("arrow_right", "27a1"); A("back", "1f519"); A("on", "1f51b"); A("soon", "1f51c"); A("top", "1f51d"); A("help", "1f198"); A("stop", "1f6d1"); A("no_entry", "26d4"); A("mountain", "26f0"); A("camping", "1f3d5"); A("tent", "26fa"); A("rope", "1f9f6"); A("backpack", "1f392"); A("flashlight", "1f526"); A("compass", "1f9ed"); A("map", "1f5fa"); A("rock", "1faa8"); A("wood", "1fab5"); A("honey", "1f36f"); A("bee", "1f41d"); A("bug", "1f41b"); static void A(string name, string code) { code = NormalizeCodeKey(code); if (!_shortcodes.ContainsKey(name)) { _shortcodes[name] = code; } if (!_codeToShortcode.ContainsKey(code)) { _codeToShortcode[code] = name; } } } } [Flags] internal enum BdmEmojiCategory { None = 0, Faces = 1, Gestures = 2, People = 4, Animals = 8, Food = 0x10, Travel = 0x20, Activities = 0x40, Objects = 0x80, Symbols = 0x100, Flags = 0x200, All = 0x3FF } internal static class BdmEmojiCategoryUtil { internal static readonly (BdmEmojiCategory Cat, string Label)[] CheckboxOrder = new(BdmEmojiCategory, string)[10] { (BdmEmojiCategory.Faces, "Faces"), (BdmEmojiCategory.Gestures, "Gestures"), (BdmEmojiCategory.People, "People"), (BdmEmojiCategory.Animals, "Animals"), (BdmEmojiCategory.Food, "Food"), (BdmEmojiCategory.Travel, "Travel"), (BdmEmojiCategory.Activities, "Activities"), (BdmEmojiCategory.Objects, "Objects"), (BdmEmojiCategory.Symbols, "Symbols"), (BdmEmojiCategory.Flags, "Flags") }; internal static BdmEmojiCategory ClassifyCodeKey(string codeKey) { if (string.IsNullOrEmpty(codeKey)) { return BdmEmojiCategory.Symbols; } string[] array = codeKey.Split(new char[1] { '_' }); if (array.Length >= 2 && TryParseCp(array[0], out var cp) && TryParseCp(array[1], out var cp2) && IsRegionalIndicator(cp) && IsRegionalIndicator(cp2)) { return BdmEmojiCategory.Flags; } if (array.Length == 1 && TryParseCp(array[0], out var cp3) && IsRegionalIndicator(cp3)) { return BdmEmojiCategory.Symbols; } return ClassifyCp(GetPrimaryCp(array)); } private static uint GetPrimaryCp(string[] parts) { for (int i = 0; i < parts.Length; i++) { if (TryParseCp(parts[i], out var cp) && (cp < 127995 || cp > 127999) && cp != 65039 && cp != 8205 && cp != 8419) { return cp; } } return 0u; } private static bool TryParseCp(string hex, out uint cp) { return uint.TryParse(hex, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out cp); } private static bool IsRegionalIndicator(uint cp) { return cp >= 127462 && cp <= 127487; } private static bool In(uint cp, uint lo, uint hi) { return cp >= lo && cp <= hi; } private static BdmEmojiCategory ClassifyCp(uint cp) { if (cp == 0) { return BdmEmojiCategory.Symbols; } if (IsRegionalIndicator(cp) || cp == 127988 || cp == 127987) { return BdmEmojiCategory.Flags; } if (In(cp, 9994u, 9997u) || cp == 9757 || In(cp, 128070u, 128080u) || cp == 128588 || cp == 128591 || In(cp, 128400u, 128406u) || In(cp, 129304u, 129311u) || cp == 129292 || In(cp, 129776u, 129784u) || cp == 128170 || cp == 129309) { return BdmEmojiCategory.Gestures; } if (In(cp, 128512u, 128591u)) { if (In(cp, 128581u, 128587u)) { return BdmEmojiCategory.People; } return BdmEmojiCategory.Faces; } if (In(cp, 129296u, 129327u) || In(cp, 129392u, 129402u) || cp == 129488 || In(cp, 129760u, 129768u) || cp == 9785 || cp == 9786 || cp == 10084 || cp == 10083 || In(cp, 128139u, 128159u) || cp == 128420 || In(cp, 129293u, 129294u) || cp == 129505 || In(cp, 129653u, 129655u) || In(cp, 128162u, 128171u) || cp == 128175) { return BdmEmojiCategory.Faces; } if (In(cp, 128102u, 128120u) || cp == 128124 || In(cp, 129489u, 129503u) || In(cp, 128372u, 128373u) || cp == 127877 || In(cp, 129328u, 129337u) || In(cp, 129456u, 129459u) || In(cp, 129461u, 129462u) || In(cp, 129464u, 129465u) || In(cp, 128081u, 128099u) || In(cp, 129506u, 129510u) || In(cp, 129648u, 129652u) || In(cp, 128064u, 128069u) || In(cp, 129467u, 129471u) || In(cp, 129728u, 129733u)) { return BdmEmojiCategory.People; } if (cp == 9749) { return BdmEmojiCategory.Food; } if (In(cp, 128000u, 128063u) || In(cp, 129408u, 129454u) || cp == 128330 || In(cp, 127792u, 127811u) || In(cp, 127744u, 127788u) || In(cp, 129440u, 129453u) || In(cp, 129712u, 129727u) || cp == 9728 || cp == 9729 || cp == 9924 || cp == 9925 || cp == 9889 || cp == 9748) { return BdmEmojiCategory.Animals; } if (In(cp, 127789u, 127871u) || In(cp, 129360u, 129391u) || In(cp, 129472u, 129483u) || In(cp, 129744u, 129753u)) { return BdmEmojiCategory.Food; } if (In(cp, 127995u, 127999u)) { return BdmEmojiCategory.People; } if (In(cp, 128640u, 128767u) || In(cp, 127956u, 127967u) || In(cp, 127968u, 127984u) || In(cp, 128506u, 128511u) || cp == 127757 || cp == 127758 || cp == 127759 || In(cp, 9968u, 9973u) || cp == 9978) { return BdmEmojiCategory.Travel; } if (In(cp, 127904u, 127951u) || In(cp, 127872u, 127903u) || In(cp, 129344u, 129359u) || In(cp, 9917u, 9918u) || cp == 129511 || In(cp, 129664u, 129670u)) { return BdmEmojiCategory.Activities; } if (In(cp, 128160u, 128255u) || In(cp, 128256u, 128317u) || In(cp, 128336u, 128359u) || In(cp, 128368u, 128505u) || In(cp, 129512u, 129535u) || In(cp, 129680u, 129711u) || In(cp, 8986u, 9000u) || cp == 9200 || cp == 9203) { return BdmEmojiCategory.Objects; } if (In(cp, 8592u, 8703u) || In(cp, 8960u, 9215u) || In(cp, 9632u, 9727u) || In(cp, 9728u, 9983u) || In(cp, 9984u, 10175u) || In(cp, 11008u, 11263u) || In(cp, 127377u, 127569u) || In(cp, 48u, 57u) || cp == 35 || cp == 42 || In(cp, 127344u, 127373u) || In(cp, 127280u, 127311u)) { return BdmEmojiCategory.Symbols; } return BdmEmojiCategory.Objects; } } internal static class BdmEmojiLayoutStore { private const string FileName = "emoji_menu_layout.txt"; internal static bool TryLoad(out float x, out float y) { x = 0f; y = 0f; try { string path = GetPath(); if (!File.Exists(path)) { return false; } float result = 0f; float result2 = 0f; bool flag = false; bool flag2 = false; string[] array = File.ReadAllLines(path); foreach (string text in array) { string text2 = text.Trim(); if (text2.Length == 0 || text2.StartsWith("#")) { continue; } int num = text2.IndexOf('='); if (num > 0) { string text3 = text2.Substring(0, num).Trim(); string s = text2.Substring(num + 1).Trim(); if (text3.Equals("x", StringComparison.OrdinalIgnoreCase) && float.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out result)) { flag = true; } else if (text3.Equals("y", StringComparison.OrdinalIgnoreCase) && float.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out result2)) { flag2 = true; } } } if (!flag || !flag2) { return false; } x = result; y = result2; return true; } catch (Exception ex) { BlindDeafMuteChallengePlugin.Instance?.LogDebug("[BlindDeafMute] emoji_menu_layout load failed: " + ex.Message); return false; } } internal static void Save(float x, float y) { try { string path = GetPath(); string contents = "# BDM emoji menu window position (screen pixels)\nx=" + x.ToString("0.###", CultureInfo.InvariantCulture) + "\ny=" + y.ToString("0.###", CultureInfo.InvariantCulture) + "\n"; File.WriteAllText(path, contents); } catch (Exception ex) { BlindDeafMuteChallengePlugin.Instance?.LogDebug("[BlindDeafMute] emoji_menu_layout save failed: " + ex.Message); } } private static string GetPath() { string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? string.Empty; return Path.Combine(path, "emoji_menu_layout.txt"); } } internal sealed class BdmEmojiMenu : MonoBehaviour { private sealed class EmojiCell { internal GameObject Root; internal RectTransform Rt; internal RawImage Image; internal Button Button; internal BdmEmojiCatalog.Entry Entry; internal bool AllowFavoriteToggle; } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction <>9__47_0; internal void b__47_0() { Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter != (Object)null) { BdmEmojiNet.ClearStringFromLocal(localCharacter); } } } private const int SortOrder = 9100; private const float SearchDebounceSeconds = 0.18f; private static BdmEmojiMenu _instance; private Canvas _canvas; private RectTransform _panel; private Image _panelImage; private TextMeshProUGUI _title; private TextMeshProUGUI _cacheLabel; private TextMeshProUGUI _infoLabel; private TextMeshProUGUI _favHeader; private TextMeshProUGUI _recentHeader; private RectTransform _favRow; private RectTransform _recentRow; private TMP_InputField _search; private Toggle _skinToggle; private ScrollRect _gridScroll; private RectTransform _gridContent; private readonly List _categoryToggles = new List(12); private readonly List _favCells = new List(16); private readonly List _recentCells = new List(16); private readonly List _gridPool = new List(64); private bool _visible; private bool _built; private bool _builtWithPeakButtons; private string _query = string.Empty; private string _lastFilteredQuery = "\0"; private bool _filterPending; private float _filterAt; private bool _blockAlphabetWhenFiltered; private bool _excludeSkinWhenFiltered; private BdmEmojiCategory _categoryMaskWhenFiltered = BdmEmojiCategory.All; private BdmEmojiCategory _categoryMask = BdmEmojiCategory.All; private readonly List _filtered = new List(256); private int _gridColumns = 16; private float _cellSize = 56f; private float _gridPad = 4f; private CursorLockMode _prevLock; private bool _prevCursorVisible; private Vector2 _frozenLookValues; private bool _hasFrozenLook; public static bool IsOpen => (Object)(object)_instance != (Object)null && _instance._visible && ((Component)_instance).gameObject.activeInHierarchy; public static void EnsureCreated() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown if (!((Object)(object)_instance != (Object)null)) { GameObject val = new GameObject("BDM_EmojiMenu"); Object.DontDestroyOnLoad((Object)(object)val); _instance = val.AddComponent(); val.SetActive(false); } } public static void OpenFromHotkey() { EnsureCreated(); if (!_instance._visible) { _instance.Open(); } } public static void Close() { if ((Object)(object)_instance != (Object)null) { _instance.CloseInternal(); } } public static void DestroyInstance() { if (!((Object)(object)_instance == (Object)null)) { Object.Destroy((Object)(object)((Component)_instance).gameObject); _instance = null; } } private void Build() { //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_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Expected O, but got Unknown //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Expected O, but got Unknown //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_03dd: Unknown result type (might be due to invalid IL or missing references) //IL_0415: Unknown result type (might be due to invalid IL or missing references) //IL_0424: Unknown result type (might be due to invalid IL or missing references) //IL_042e: Expected O, but got Unknown //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Expected O, but got Unknown if (_built) { return; } _built = true; _builtWithPeakButtons = BdmPeakUi.HasPeakButtonDonor(); _categoryToggles.Clear(); _favCells.Clear(); _recentCells.Clear(); _gridPool.Clear(); _canvas = BdmPeakUi.CreateOverlayCanvas(((Component)this).gameObject, 9100); _panel = BdmPeakUi.CreatePanel(((Component)this).transform, "Panel", new Vector2(1000f, 900f), BdmPeakUi.PanelColor); _panelImage = ((Component)_panel).GetComponent(); BdmPeakUi.AddVerticalLayout(((Component)_panel).gameObject, 6f, new RectOffset(16, 16, 12, 12)); GameObject val = new GameObject("TitleBar", new Type[1] { typeof(RectTransform) }); val.transform.SetParent((Transform)(object)_panel, false); val.AddComponent().preferredHeight = 34f; _title = BdmPeakUi.CreateLabel(val.transform, "Title", "Emoji (Mute)", 24f, (FontStyles)0, (TextAlignmentOptions)514); BdmPeakUi.Stretch(((TMP_Text)_title).rectTransform, 0f, 0f); BdmPeakUi.MakeDraggable(val, _panel, SavePosition); GameObject val2 = new GameObject("Top", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent((Transform)(object)_panel, false); val2.AddComponent().preferredHeight = 36f; ((HorizontalOrVerticalLayoutGroup)BdmPeakUi.AddHorizontalLayout(val2, 10f)).childForceExpandWidth = true; Transform transform = val2.transform; object obj = <>c.<>9__47_0; if (obj == null) { UnityAction val3 = delegate { Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter != (Object)null) { BdmEmojiNet.ClearStringFromLocal(localCharacter); } }; <>c.<>9__47_0 = val3; obj = (object)val3; } BdmPeakUi.CreateButton(transform, "Clear String", (UnityAction)obj, new Vector2(140f, 32f)); _cacheLabel = BdmPeakUi.CreateLabel(val2.transform, "Cache", "Cached: 0", 16f, (FontStyles)0, (TextAlignmentOptions)516); ((Component)_cacheLabel).gameObject.AddComponent().flexibleWidth = 1f; _skinToggle = BdmPeakUi.CreateToggle((Transform)(object)_panel, "Show skin-tone variants", isOn: false, delegate(bool v) { BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; if (!((Object)(object)instance == (Object)null)) { if (PhotonNetwork.InRoom && !PhotonNetwork.IsMasterClient && !BdmModAuthorizationService.IsClientOnlyFallback()) { BdmPeakUi.SetToggleVisual(_skinToggle, instance.ShowSkinToneVariants); } else { instance.SetShowSkinToneVariantsLocal(v); QueueRefilterNow(); } } }); BuildCategoryRow(); _favHeader = BdmPeakUi.CreateLabel((Transform)(object)_panel, "FavHeader", "Favorites (Ctrl+click to toggle)", 16f, (FontStyles)0, (TextAlignmentOptions)513); BdmPeakUi.MakeNonCollapsing(((Component)_favHeader).gameObject, 24f, 200f); _favRow = CreateEmojiStrip("Favorites"); _recentHeader = BdmPeakUi.CreateLabel((Transform)(object)_panel, "RecentHeader", "Recents", 16f, (FontStyles)0, (TextAlignmentOptions)513); BdmPeakUi.MakeNonCollapsing(((Component)_recentHeader).gameObject, 24f, 80f); _recentRow = CreateEmojiStrip("Recents"); TextMeshProUGUI val4 = BdmPeakUi.CreateLabel((Transform)(object)_panel, "SearchLabel", "Search (finds any category, even if unchecked):", 15f, (FontStyles)0, (TextAlignmentOptions)513); BdmPeakUi.MakeNonCollapsing(((Component)val4).gameObject, 22f, 280f); _search = BdmPeakUi.CreateSearchField((Transform)(object)_panel, "Search…", delegate(string s) { _query = s ?? string.Empty; _filterPending = true; _filterAt = Time.unscaledTime + 0.18f; }); _gridScroll = BdmPeakUi.CreateScrollView((Transform)(object)_panel, out _gridContent); ((Component)_gridScroll).gameObject.AddComponent().flexibleHeight = 1f; ((UnityEvent)(object)_gridScroll.onValueChanged).AddListener((UnityAction)delegate { RefreshVirtualGrid(); }); _infoLabel = BdmPeakUi.CreateLabel((Transform)(object)_panel, "Info", string.Empty, 15f, (FontStyles)0, (TextAlignmentOptions)513); ((Graphic)_infoLabel).color = BdmPeakUi.CreamDim; ((Component)_infoLabel).gameObject.AddComponent().preferredHeight = 24f; BdmPeakUi.CreateButton((Transform)(object)_panel, "Close", new UnityAction(CloseInternal), new Vector2(120f, 34f)); } private void BuildCategoryRow() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Expected O, but got Unknown //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Expected O, but got Unknown GameObject val = new GameObject("CatHeader", new Type[1] { typeof(RectTransform) }); val.transform.SetParent((Transform)(object)_panel, false); val.AddComponent().preferredHeight = 30f; BdmPeakUi.AddHorizontalLayout(val, 8f); BdmPeakUi.CreateLabel(val.transform, "Show", "Show:", 16f, (FontStyles)0, (TextAlignmentOptions)513); BdmPeakUi.CreateButton(val.transform, "All", (UnityAction)delegate { _categoryMask = BdmEmojiCategory.All; SyncCategoryToggles(); QueueRefilterNow(); }, new Vector2(56f, 26f)); BdmPeakUi.CreateButton(val.transform, "None", (UnityAction)delegate { _categoryMask = BdmEmojiCategory.None; SyncCategoryToggles(); QueueRefilterNow(); }, new Vector2(64f, 26f)); (BdmEmojiCategory, string)[] checkboxOrder = BdmEmojiCategoryUtil.CheckboxOrder; GameObject val2 = null; for (int num = 0; num < checkboxOrder.Length; num++) { if (num % 5 == 0) { val2 = new GameObject("CatRow" + num, new Type[1] { typeof(RectTransform) }); val2.transform.SetParent((Transform)(object)_panel, false); val2.AddComponent().preferredHeight = 28f; BdmPeakUi.AddHorizontalLayout(val2, 6f); } BdmEmojiCategory cat = checkboxOrder[num].Item1; string item = checkboxOrder[num].Item2; Toggle val3 = BdmPeakUi.CreateToggle(val2.transform, item, isOn: true, delegate(bool v) { if (v) { _categoryMask |= cat; } else { _categoryMask &= ~cat; } QueueRefilterNow(); }); LayoutElement component = ((Component)val3).GetComponent(); if ((Object)(object)component != (Object)null) { component.flexibleWidth = 0f; } _categoryToggles.Add(val3); } } private RectTransform CreateEmojiStrip(string name) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown GameObject val = new GameObject(name, new Type[2] { typeof(RectTransform), typeof(Image) }); val.transform.SetParent((Transform)(object)_panel, false); ((Graphic)val.GetComponent()).color = new Color(0.05f, 0.04f, 0.03f, 0.4f); val.AddComponent().preferredHeight = 64f; LayoutElement component = val.GetComponent(); component.minHeight = 64f; component.flexibleHeight = 0f; HorizontalLayoutGroup val2 = BdmPeakUi.AddHorizontalLayout(val, 4f); ((LayoutGroup)val2).padding = new RectOffset(4, 4, 4, 4); ((HorizontalOrVerticalLayoutGroup)val2).childForceExpandWidth = false; return val.GetComponent(); } private void Open() { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) if (!CanMuteUseMenu()) { BlindDeafMuteChallengePlugin.Instance?.LogAlways("[BlindDeafMute] Emoji menu is for Mute players only."); return; } if (_built && !_builtWithPeakButtons && BdmPeakUi.HasPeakButtonDonor()) { SavePosition(); TearDownUi(); } Build(); BdmEmojiCatalog.EnsureLoaded(); BdmEmojiUserLists.EnsureLoaded(); _prevLock = Cursor.lockState; _prevCursorVisible = Cursor.visible; _visible = true; _query = string.Empty; if ((Object)(object)_search != (Object)null) { _search.SetTextWithoutNotify(string.Empty); } _lastFilteredQuery = "\0"; _filterPending = true; _filterAt = 0f; SetInfo(BdmEmojiCatalog.IsPreloadDone ? "Left-click send · Ctrl+click favorite · Search finds all categories" : $"Loading emoji textures… {BdmEmojiCatalog.PreloadLoadedCount}/{BdmEmojiCatalog.Count}"); ApplyWindowSizeFromConfig(); RestoreOrCenterPosition(); ApplyChromeColor(); SyncSkinToggle(); SyncCategoryToggles(); Refilter(force: true); RefreshPinnedRows(); ((Component)this).gameObject.SetActive(true); RefreshVirtualGrid(); BdmPeakUi.ApplyAllFonts(((Component)this).transform); ApplyMenuInputBlock(block: true); CaptureFrozenLook(); Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter != (Object)null) { BdmEmojiNet.SetReactingFromLocal(localCharacter, reacting: true); } } private void TearDownUi() { for (int num = ((Component)this).transform.childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)((Component)this).transform.GetChild(num)).gameObject); } _categoryToggles.Clear(); _favCells.Clear(); _recentCells.Clear(); _gridPool.Clear(); _panel = null; _panelImage = null; _title = null; _cacheLabel = null; _infoLabel = null; _favHeader = null; _recentHeader = null; _favRow = null; _recentRow = null; _search = null; _skinToggle = null; _gridScroll = null; _gridContent = null; _canvas = null; _built = false; _builtWithPeakButtons = false; BdmPeakUi.InvalidateButtonDonor(); } private void CloseInternal() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) if (_visible) { SavePosition(); _visible = false; _hasFrozenLook = false; if ((Object)(object)_search != (Object)null) { _search.DeactivateInputField(false); } BdmPeakUi.ReleaseUiFocus(); ApplyMenuInputBlock(block: false); Cursor.lockState = _prevLock; Cursor.visible = _prevCursorVisible; ((Component)this).gameObject.SetActive(false); Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter != (Object)null) { BdmEmojiNet.SetReactingFromLocal(localCharacter, reacting: false); } } } private void LateUpdate() { if (_visible) { ApplyMenuInputBlock(block: true); Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; HoldFrozenLook(); ApplyChromeColor(); ApplyWindowSizeFromConfig(); BdmPeakUi.ApplyAllFonts(((Component)this).transform); if (Time.frameCount % 2 == 0) { RefreshVirtualGrid(); } } } private void Update() { if (!_visible) { return; } if (!CanMuteUseMenu()) { CloseInternal(); return; } if ((Object)(object)_cacheLabel != (Object)null) { ((TMP_Text)_cacheLabel).text = $"Cached: {BdmEmojiCatalog.Count}"; BdmGameUiFont.Apply(_cacheLabel); } if (!BdmEmojiCatalog.IsPreloadDone) { SetInfo($"Loading emoji textures… {BdmEmojiCatalog.PreloadLoadedCount}/{BdmEmojiCatalog.Count}"); } if (_filterPending && Time.unscaledTime >= _filterAt) { _filterPending = false; Refilter(force: false); RefreshPinnedRows(); RefreshVirtualGrid(); } } private void SyncSkinToggle() { BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; if (!((Object)(object)instance == (Object)null) && !((Object)(object)_skinToggle == (Object)null)) { bool flag = !PhotonNetwork.InRoom || PhotonNetwork.IsMasterClient || BdmModAuthorizationService.IsClientOnlyFallback(); ((Selectable)_skinToggle).interactable = flag; BdmPeakUi.SetToggleVisual(_skinToggle, instance.ShowSkinToneVariants); TextMeshProUGUI componentInChildren = ((Component)_skinToggle).GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { ((TMP_Text)componentInChildren).text = (flag ? "Show skin-tone variants" : "Show skin-tone variants (host)"); BdmGameUiFont.Apply(componentInChildren); } } } private void SyncCategoryToggles() { (BdmEmojiCategory, string)[] checkboxOrder = BdmEmojiCategoryUtil.CheckboxOrder; for (int i = 0; i < _categoryToggles.Count && i < checkboxOrder.Length; i++) { bool isOn = (_categoryMask & checkboxOrder[i].Item1) != 0; BdmPeakUi.SetToggleVisual(_categoryToggles[i], isOn); } } private void QueueRefilterNow() { _filterPending = true; _filterAt = 0f; } private void Refilter(bool force) { bool flag = (Object)(object)BlindDeafMuteChallengePlugin.Instance != (Object)null && BlindDeafMuteChallengePlugin.Instance.BlockAlphabetEmojis; bool flag2 = (Object)(object)BlindDeafMuteChallengePlugin.Instance == (Object)null || !BlindDeafMuteChallengePlugin.Instance.ShowSkinToneVariants; if (force || !(_query == _lastFilteredQuery) || flag != _blockAlphabetWhenFiltered || flag2 != _excludeSkinWhenFiltered || _categoryMask != _categoryMaskWhenFiltered || _filtered.Count <= 0) { _lastFilteredQuery = _query; _blockAlphabetWhenFiltered = flag; _excludeSkinWhenFiltered = flag2; _categoryMaskWhenFiltered = _categoryMask; BdmEmojiCatalog.Filter(_query, _filtered, flag, flag2, _categoryMask); if ((Object)(object)_gridScroll != (Object)null) { _gridScroll.verticalNormalizedPosition = 1f; } } } private void RefreshPinnedRows() { FillStrip(_favRow, _favCells, BdmEmojiUserLists.Favorites, allowFavoriteToggle: true); FillStrip(_recentRow, _recentCells, BdmEmojiUserLists.Recents, allowFavoriteToggle: false); } private void FillStrip(RectTransform row, List pool, IReadOnlyList codes, bool allowFavoriteToggle) { if ((Object)(object)row == (Object)null) { return; } EnsureStripCells(row, pool, codes?.Count ?? 0, allowFavoriteToggle); int num = 0; if (codes != null) { for (int i = 0; i < codes.Count; i++) { BdmEmojiCatalog.Entry entry = BdmEmojiCatalog.FindByCodeKey(codes[i]); if (entry != null) { BindCell(pool[num], entry, allowFavoriteToggle, _cellSize * 0.85f); pool[num].Root.SetActive(true); num++; } } } for (int j = num; j < pool.Count; j++) { pool[j].Root.SetActive(false); } } private void EnsureStripCells(RectTransform row, List pool, int count, bool allowFavoriteToggle) { while (pool.Count < count) { pool.Add(CreateCell((Transform)(object)row, allowFavoriteToggle)); } } private void RefreshVirtualGrid() { //IL_004e: 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_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_gridContent == (Object)null || (Object)(object)_gridScroll == (Object)null) { return; } float num; Rect rect; if (!((Object)(object)_gridScroll.viewport != (Object)null)) { num = 400f; } else { rect = _gridScroll.viewport.rect; num = ((Rect)(ref rect)).height; } float num2 = num; float num3; if (!((Object)(object)_gridScroll.viewport != (Object)null)) { num3 = 900f; } else { rect = _gridScroll.viewport.rect; num3 = ((Rect)(ref rect)).width; } float num4 = num3; if (num4 < 10f) { num4 = Mathf.Max(100f, _panel.sizeDelta.x - 40f); } int num5 = Mathf.Max(1, _gridColumns); float cellSize = _cellSize; float num6 = cellSize + _gridPad; int count = _filtered.Count; int num7 = ((count > 0) ? ((count + num5 - 1) / num5) : 0); float num8 = Mathf.Max(num2, (float)num7 * num6 + _gridPad); _gridContent.sizeDelta = new Vector2(0f, num8); int num9 = Mathf.CeilToInt(num2 / num6) + 3; int num10 = Mathf.Max(num5 * 2, num9 * num5); while (_gridPool.Count < num10) { _gridPool.Add(CreateCell((Transform)(object)_gridContent, allowFavoriteToggle: true)); } if (count == 0) { for (int i = 0; i < _gridPool.Count; i++) { _gridPool[i].Root.SetActive(false); } return; } float y = _gridContent.anchoredPosition.y; int num11 = Mathf.Clamp(Mathf.FloorToInt(y / num6) - 1, 0, Mathf.Max(0, num7 - 1)); int num12 = Mathf.Min(num7 - 1, num11 + num9); int num13 = 0; Vector2 val = default(Vector2); for (int j = num11; j <= num12; j++) { for (int k = 0; k < num5; k++) { int num14 = j * num5 + k; if (num14 >= count || num13 >= _gridPool.Count) { break; } EmojiCell emojiCell = _gridPool[num13++]; BindCell(emojiCell, _filtered[num14], allowFavoriteToggle: true, cellSize); RectTransform rt = emojiCell.Rt; RectTransform rt2 = emojiCell.Rt; ((Vector2)(ref val))..ctor(0f, 1f); rt2.anchorMax = val; rt.anchorMin = val; emojiCell.Rt.pivot = new Vector2(0f, 1f); emojiCell.Rt.sizeDelta = new Vector2(cellSize, cellSize); emojiCell.Rt.anchoredPosition = new Vector2((float)k * num6 + _gridPad, 0f - ((float)j * num6 + _gridPad)); emojiCell.Root.SetActive(true); } } for (int l = num13; l < _gridPool.Count; l++) { _gridPool[l].Root.SetActive(false); } } private EmojiCell CreateCell(Transform parent, bool allowFavoriteToggle) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown //IL_0069: 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_00cd: Expected O, but got Unknown GameObject val = new GameObject("EmojiCell", new Type[4] { typeof(RectTransform), typeof(CanvasRenderer), typeof(RawImage), typeof(Button) }); val.transform.SetParent(parent, false); RawImage component = val.GetComponent(); ((Graphic)component).color = Color.white; Button component2 = val.GetComponent