Decompiled source of ChatX v3.1.0
ChatX.dll
Decompiled 2 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Mirror; using Nessie.ATLYSS.EasySettings; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ChatX")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("3.1.0.0")] [assembly: AssemblyInformationalVersion("3.1.0+4c913a7c0d55f8366ddcb3969839b76de08d1c83")] [assembly: AssemblyProduct("ChatX")] [assembly: AssemblyTitle("ChatX")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("3.1.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ChatX { internal sealed class ChatLinkClickHandler : MonoBehaviour, IPointerClickHandler, IEventSystemHandler, IPointerDownHandler, IPointerUpHandler, IInitializePotentialDragHandler, IBeginDragHandler, IDragHandler, IEndDragHandler, IScrollHandler { private ChatBehaviourAssets _assets; private ScrollRect _scrollRect; private TextMeshProUGUI _chatText; private bool _dragInProgress; internal void Bind(ChatBehaviourAssets assets, ScrollRect scrollRect, TextMeshProUGUI chatText) { _assets = assets; _scrollRect = scrollRect; _chatText = chatText; } public void OnPointerClick(PointerEventData eventData) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) if (eventData == null || (int)eventData.button != 0 || _dragInProgress || (Object)(object)_chatText == (Object)null || ChatX.IsChatLinkPromptOpen) { return; } Camera val = eventData.pressEventCamera ?? eventData.enterEventCamera; int num = TMP_TextUtilities.FindIntersectingLink((TMP_Text)(object)_chatText, Vector2.op_Implicit(eventData.position), val); if (num >= 0 && num < ((TMP_Text)_chatText).textInfo.linkCount) { string linkID = ((TMP_LinkInfo)(ref ((TMP_Text)_chatText).textInfo.linkInfo[num])).GetLinkID(); if (!string.IsNullOrWhiteSpace(linkID)) { ChatX.ShowChatLinkPrompt(_assets, linkID); } } } public void OnPointerDown(PointerEventData eventData) { _dragInProgress = false; } public void OnPointerUp(PointerEventData eventData) { _dragInProgress = false; } public void OnInitializePotentialDrag(PointerEventData eventData) { ForwardToScrollRect<IInitializePotentialDragHandler>((BaseEventData)(object)eventData, ExecuteEvents.initializePotentialDrag); } public void OnBeginDrag(PointerEventData eventData) { _dragInProgress = true; ForwardToScrollRect<IBeginDragHandler>((BaseEventData)(object)eventData, ExecuteEvents.beginDragHandler); } public void OnDrag(PointerEventData eventData) { _dragInProgress = true; ForwardToScrollRect<IDragHandler>((BaseEventData)(object)eventData, ExecuteEvents.dragHandler); } public void OnEndDrag(PointerEventData eventData) { ForwardToScrollRect<IEndDragHandler>((BaseEventData)(object)eventData, ExecuteEvents.endDragHandler); _dragInProgress = false; } public void OnScroll(PointerEventData eventData) { ForwardToScrollRect<IScrollHandler>((BaseEventData)(object)eventData, ExecuteEvents.scrollHandler); } private void ForwardToScrollRect<T>(BaseEventData eventData, EventFunction<T> handler) where T : IEventSystemHandler { if (!((Object)(object)_scrollRect == (Object)null) && eventData != null) { ExecuteEvents.Execute<T>(((Component)_scrollRect).gameObject, eventData, handler); } } } [BepInPlugin("ChatX", "ChatX", "3.1.0")] public class ChatX : BaseUnityPlugin { private enum PromptButtonIconKind { Confirm, Copy, Cancel } private sealed class ProtectedChatLink { public string Token; public string DisplayText; public string CanonicalUrl; } internal sealed class ChatScrollbarState { public CanvasGroup Scrollbar; public GameObject ScrollbarObject; public Scrollbar ScrollbarComponent; public ScrollRect ScrollRect; public GameObject ChatContainer; public bool? CachedChatContainerActive; public bool? CachedChannelDockActive; } [HarmonyPatch(typeof(ChatBehaviour), "New_ChatMessage")] private static class ChatBehaviour_New_ChatMessage_PrefixAndBlock { [HarmonyPrefix] [HarmonyPriority(800)] private static bool Prefix(ref string __0) { //IL_0087: Unknown result type (might be due to invalid IL or missing references) ConfigEntry<bool> blockChat = ChatX.blockChat; if (blockChat != null && blockChat.Value) { return false; } __0 = ProtectChatLinks(__0, out var protectedLinks); string badge = ExtractRenderedOocBadge(ref __0); ConfigEntry<bool> asteriskItalic = ChatX.asteriskItalic; if (asteriskItalic != null && asteriskItalic.Value) { __0 = ApplyAsteriskFormatting(__0); } string prefix = string.Empty; ConfigEntry<bool> chatPrefix = ChatX.chatPrefix; if (chatPrefix != null && chatPrefix.Value && !LooksPrefixed(__0) && TryExtractChatChannel(__0, out var channel)) { prefix = BuildMessagePrefix(channel); } string text = CombinePrefixSegments(prefix, badge); if (!string.IsNullOrEmpty(text)) { __0 = InsertPrefix(__0, text); } ApplyMentionEffects(ref __0); __0 = RestoreProtectedChatLinks(__0, protectedLinks); return true; } [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix(ChatBehaviour __instance) { if (Object.op_Implicit((Object)(object)__instance)) { EnsureChatLinkUi(__instance._chatAssets); ApplyOpacityCap(__instance._chatAssets); } } } [HarmonyPatch(typeof(ChatBehaviour), "Init_GameLogicMessage")] private static class ChatBehaviour_Init_GameLogicMessage_Block { [HarmonyPrefix] [HarmonyPriority(800)] private static bool Prefix() { ConfigEntry<bool> blockGameFeed = ChatX.blockGameFeed; return blockGameFeed == null || !blockGameFeed.Value; } } [HarmonyPatch(typeof(PatternInstanceManager), "On_DungeonKeyChange")] private static class PatternInstanceManager_OnDungeonKeyChange_Reroute { private static readonly MethodInfo NewChatMessage = AccessTools.Method(typeof(ChatBehaviour), "New_ChatMessage", (Type[])null, (Type[])null); private static readonly MethodInfo PushGameFeed = AccessTools.Method(typeof(ChatX), "PushGameFeedMessage", (Type[])null, (Type[])null); private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { return ReplaceMethodCalls(instructions, NewChatMessage, PushGameFeed, 2, "PatternInstanceManager.On_DungeonKeyChange reroute"); } } [HarmonyPatch(typeof(PlayerQuesting), "Accept_Quest")] private static class PlayerQuesting_AcceptQuest_RerouteObjectivePickup { private static readonly MethodInfo NewChatMessage = AccessTools.Method(typeof(ChatBehaviour), "New_ChatMessage", (Type[])null, (Type[])null); private static readonly MethodInfo PushGameFeed = AccessTools.Method(typeof(ChatX), "PushGameFeedMessage", (Type[])null, (Type[])null); private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { return ReplaceMethodCalls(instructions, NewChatMessage, PushGameFeed, 1, "PlayerQuesting.Accept_Quest reroute"); } } [HarmonyPatch(typeof(WorldPortalWaypoint), "OnTriggerEnter")] private static class WorldPortalWaypoint_OnTriggerEnter_RerouteAttuneChat { private static readonly MethodInfo NewChatMessage = AccessTools.Method(typeof(ChatBehaviour), "New_ChatMessage", (Type[])null, (Type[])null); private static readonly MethodInfo RouteAttune = AccessTools.Method(typeof(ChatX), "RouteWaypointAttuneMessage", (Type[])null, (Type[])null); private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { return ReplaceMethodCalls(instructions, NewChatMessage, RouteAttune, 1, "WorldPortalWaypoint.OnTriggerEnter reroute"); } } [HarmonyPatch(typeof(NetTrigger))] private static class NetTrigger_OnTriggerStay_RerouteDungeonKeyMessage { private static readonly MethodInfo TargetReceive = AccessTools.Method(typeof(ChatBehaviour), "Target_RecieveMessage", (Type[])null, (Type[])null); private static readonly MethodInfo RouteTarget = AccessTools.Method(typeof(ChatX), "PushTargetedGameFeedMessage", (Type[])null, (Type[])null); private static MethodBase TargetMethod() { return AccessTools.Method(typeof(NetTrigger), "OnTriggerStay", (Type[])null, (Type[])null); } private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { return ReplaceMethodCalls(instructions, TargetReceive, RouteTarget, 1, "NetTrigger.OnTriggerStay reroute"); } } [HarmonyPatch(typeof(ChatBehaviour), "UserCode_Target_RecieveMessage__String")] private static class ChatBehaviour_TargetReceiveMessage_RerouteDungeonKey { private const string DoorLockedMessage = "The door is locked. It requires a Dungeon Key."; private static bool Prefix(ChatBehaviour __instance, string _message) { if (!ShouldPushGameFeed()) { return true; } if (!Object.op_Implicit((Object)(object)__instance) || string.IsNullOrEmpty(_message)) { return true; } if (!string.Equals(_message, "The door is locked. It requires a Dungeon Key.", StringComparison.Ordinal)) { return true; } PushGameFeedMessage(__instance, _message); return false; } } [HarmonyPatch(typeof(ChatBehaviour), "Display_Chat")] private static class ChatBehaviourDisplayPatch { private static void Postfix(ChatBehaviour __instance) { if (Object.op_Implicit((Object)(object)__instance)) { ApplyOpacityCap(__instance._chatAssets); } } } [HarmonyPatch(typeof(ChatBehaviour), "Client_HandleChatboxUpdate")] private static class ChatBehaviour_CapOpacity_Postfix { [HarmonyPostfix] private static void Postfix(ChatBehaviour __instance) { if (Object.op_Implicit((Object)(object)__instance)) { ApplyOpacityCap(__instance._chatAssets); } } } [HarmonyPatch(typeof(ChatBehaviour), "Client_HandleChatboxUpdate")] private static class ChatBehaviour_HandleChatControls_PreOpen { [HarmonyPrefix] [HarmonyPriority(800)] private static void Prefix(ChatBehaviour __instance) { if (Object.op_Implicit((Object)(object)__instance) && ((NetworkBehaviour)__instance).isLocalPlayer && ChatBehaviour._current == __instance && IsChatSubmitKeyPressed()) { ChatBehaviourAssets chatAssets = __instance._chatAssets; bool flag = ChatInputResolver.TryGet(chatAssets)?.IsFocused ?? false; CanvasGroup val = (Object.op_Implicit((Object)(object)chatAssets) ? chatAssets._generalCanvasGroup : null); bool flag2 = Object.op_Implicit((Object)(object)val) && val.blocksRaycasts && val.interactable; bool flag3 = Object.op_Implicit((Object)(object)val) && val.alpha <= 0.001f && !flag2; if (!(__instance._focusedInChat || flag) && flag3) { pendingRestore = true; ResetChatFocus(); } } } } [HarmonyPatch(typeof(SettingsManager), "Load_SettingsData")] private static class ChatInputLimit_OnLoad { private static void Postfix() { ChatInputCharacterLimiter.ApplyCharacterLimit(); ChatWindowResizer.ApplyAll(); } } [HarmonyPatch(typeof(SettingsManager), "Save_SettingsData")] private static class ChatInputLimit_OnSave { private static void Postfix() { ChatInputCharacterLimiter.ApplyCharacterLimit(); ChatWindowResizer.ApplyAll(); } } [HarmonyPatch(typeof(ChatBehaviourAssets), "Start")] private static class ChatInputLimit_OnChatAssetsStart { private static void Postfix(ChatBehaviourAssets __instance) { ChatWindowResizer.Register(__instance); EnsureChatLinkUi(__instance); ChatInputHandle chatInputHandle = ChatInputResolver.TryGet(__instance); if (chatInputHandle != null) { chatInputHandle.CharacterLimit = GetMaxMessageLength(); } } } [HarmonyPatch(typeof(ChatBehaviour), "OnStartAuthority")] private static class ChatBehaviour_OnStartAuthority_Patch { private static void Postfix(ChatBehaviour __instance) { ((MonoBehaviour)__instance).StartCoroutine(ChatInputCharacterLimiter.ApplyWhenReady(__instance)); } } [HarmonyPatch(typeof(InGameUI), "RefreshParams_LocatePlayer")] private static class ApplyLimit_AfterPlayerLocated { private static void Postfix() { ChatInputCharacterLimiter.ApplyCharacterLimit(); ChatWindowResizer.ApplyAll(); EnsureChatLinkUi(ChatBehaviourAssets._current); } } [HarmonyPatch(typeof(ChatBehaviour), "Send_ChatMessage")] private static class ChatBehaviour_SendMessage_Ooc { [HarmonyPrefix] [HarmonyPriority(800)] private static bool Prefix(ChatBehaviour __instance, ref string __0, out string __state) { __state = null; if (!ShouldInterceptOutgoingChat(__0)) { return true; } if (TryHandleLocalOocToggle(__instance, __0)) { return false; } string transformedMessage; string errorPrompt; switch (PrepareOutgoingChatMessage(__0, out transformedMessage, out errorPrompt)) { case OutgoingChatPreparationStatus.Suppressed: FinalizeLocalChatCommand(__instance); return false; case OutgoingChatPreparationStatus.Invalid: ShowOutgoingChatValidationError(__instance, errorPrompt, __0); return false; case OutgoingChatPreparationStatus.Transformed: __state = __0; __0 = transformedMessage; break; } return true; } [HarmonyPostfix] private static void Postfix(ChatBehaviour __instance, string __state) { if (!string.IsNullOrEmpty(__state)) { RestoreLastTypedChatMessage(__instance, __state); } } } [HarmonyPatch(typeof(ChatBehaviour), "Send_ChatMessage")] private static class ChatBehaviour_SendMessage_Transpiler { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instrs) { return ReplaceMaxLengthGuards(instrs, 1, "ChatBehaviour.Send_ChatMessage max length"); } } [HarmonyPatch(typeof(ChatBehaviour), "UserCode_Cmd_SendChatMessage__String__ChatChannel")] private static class ChatBehaviour_CmdSendMessage_Transpiler { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instrs) { return ReplaceMaxLengthGuards(instrs, 1, "ChatBehaviour.UserCode_Cmd_SendChatMessage__String__ChatChannel max length"); } } private enum OutgoingChatPreparationStatus { Unchanged, Transformed, Suppressed, Invalid } public enum MentionClip { LexiconBell, UIClick01, UIHover, Lockout } [CompilerGenerated] private static class <>O { public static UnityAction <0>__OpenPendingChatLink; public static UnityAction <1>__CopyPendingChatLink; public static UnityAction <2>__CancelPendingChatLink; public static EventHandler <3>__OnChatTallWindowChanged; public static EventHandler <4>__OnTransparentScrollbarChanged; public static EventHandler <5>__OnMentionPingChanged; public static EventHandler <6>__OnMentionPingClipChanged; public static EventHandler <7>__OnMentionPingVolumeChanged; public static EventHandler <8>__OnOocEnabledChanged; } private static readonly Type PartyUiManagerType = typeof(Player).Assembly.GetType("PartyUIManager"); private static readonly FieldInfo PartyUiCurrentField = AccessTools.Field(PartyUiManagerType, "_current"); private static readonly FieldInfo PartyInviteElementField = AccessTools.Field(PartyUiManagerType, "_partyInviteElement"); private static readonly FieldInfo PartyAcceptInviteButtonField = AccessTools.Field(PartyUiManagerType, "_acceptInviteButton"); private static readonly FieldInfo PartyDeclineInviteButtonField = AccessTools.Field(PartyUiManagerType, "_declineInviteButton"); private static readonly FieldInfo PartyInvitePromptField = AccessTools.Field(PartyUiManagerType, "_invitedByPrompt"); private static readonly FieldInfo PartyPanelGroupField = AccessTools.Field(PartyUiManagerType, "_partyPanelGroup"); private static readonly FieldInfo MenuElementRectField = AccessTools.Field(typeof(MenuElement), "menuRect"); private static readonly FieldInfo MenuElementCanvasGroupField = AccessTools.Field(typeof(MenuElement), "_canvasGroup"); private static GameObject _chatLinkPromptRoot; private static MenuElement _chatLinkPromptElement; private static CanvasGroup _chatLinkPromptCanvasGroup; private static TextMeshProUGUI _chatLinkPromptText; private static Text _chatLinkPromptTextLegacy; private static Button _chatLinkOpenButton; private static Button _chatLinkCopyButton; private static Button _chatLinkCancelButton; private static string _pendingChatLinkUrl; private static bool _chatLinkPromptOpen; private const string ChatLinkOverlayName = "ChatX_LinkClickOverlay"; private static readonly Regex UrlRegex = new Regex("\\b(?:https?://|www\\.)[^\\s<]+", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant); internal static readonly ConditionalWeakTable<ChatBehaviourAssets, ChatScrollbarState> _scrollbarStates = new ConditionalWeakTable<ChatBehaviourAssets, ChatScrollbarState>(); private static bool _dialogSuppressed; private static bool pendingRestore; private static bool _chatWasHidden; internal static readonly FieldInfo ChatInputBufferField = typeof(ChatBehaviour).GetField("_inputBuffer", BindingFlags.Instance | BindingFlags.NonPublic); private static bool _loggedMissingInputBufferField; private static bool _chatHidden; internal static ManualLogSource Log; private static readonly MethodInfo GetMaxMessageLengthMethod = AccessTools.Method(typeof(ChatX), "GetMaxMessageLength", (Type[])null, (Type[])null); private static readonly MethodInfo StringLengthGetter = AccessTools.PropertyGetter(typeof(string), "Length"); internal static AudioClip _mentionAudioClip; private static float _nextMentionPingAllowedAt; private static readonly Dictionary<string, AudioClip> _mentionClipCache = new Dictionary<string, AudioClip>(StringComparer.OrdinalIgnoreCase); private static Type _cachedPlayerSoundType; private static FieldInfo[] _cachedPlayerSoundClipFields; private static Type _cachedButtonSoundType; private static FieldInfo _cachedButtonSoundHoverField; private static FieldInfo _cachedButtonSoundClickField; private static string _lastMissingMentionClipName; private const string OocToken = "[OOC]"; private const string OocPrefix = "[OOC] "; private const string OocToggleCommand = "/ooc"; private static readonly FieldInfo ChatLastMessageField = AccessTools.Field(typeof(ChatBehaviour), "_lastMessage"); private static readonly Type ErrorPromptManagerType = typeof(Player).Assembly.GetType("ErrorPromptTextManager"); private static readonly FieldInfo ErrorPromptCurrentField = AccessTools.Field(ErrorPromptManagerType, "current"); private static readonly MethodInfo ErrorPromptInitMethod = AccessTools.Method(ErrorPromptManagerType, "Init_ErrorPrompt", (Type[])null, (Type[])null); private static bool _oocModeEnabled; internal static ConfigEntry<float> chatOpacity; internal static ConfigEntry<bool> blockChat; internal static ConfigEntry<bool> blockGameFeed; internal static ConfigEntry<bool> chatPrefix; internal static ConfigEntry<bool> chatTimestamp; internal static ConfigEntry<bool> timestampFormat; internal static ConfigEntry<bool> asteriskItalic; internal static ConfigEntry<bool> oocEnabled; internal static ConfigEntry<bool> chatTallWindow; internal static ConfigEntry<KeyCode> clearChatKey; internal static ConfigEntry<KeyCode> toggleChatVisibilityKey; internal static ConfigEntry<bool> messageLimit; internal static ConfigEntry<bool> pushGameMessage; internal static ConfigEntry<bool> mentionUnderline; internal static ConfigEntry<bool> mentionPing; internal static ConfigEntry<string> mentionPingClip; internal static ConfigEntry<MentionClip> mentionPingClipEnum; internal static ConfigEntry<float> mentionPingVolume; internal static ConfigEntry<bool> transparentScrollbar; private static bool _settingsRegistered; private const string SettingsTabName = "Chat"; private static readonly MethodInfo GetOrAddCustomTabMethod = typeof(Settings).GetMethod("GetOrAddCustomTab", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(string) }, null); private static bool _loggedMissingCustomTabApi; private static readonly string[] ClipNames = new string[4] { "_lexiconBell", "_uiClick01", "_uiHover", "lockout" }; internal static bool IsChatLinkPromptOpen => _chatLinkPromptOpen; private static string NormalizeChannelColorToken(string token) { if (string.IsNullOrWhiteSpace(token)) { return string.Empty; } token = token.Trim(); if (token.StartsWith("#", StringComparison.Ordinal) && token.Length >= 7) { token = token.Substring(0, 7); } return token.ToUpperInvariant(); } private static bool TryExtractChatChannel(string message, out ChatChannel channel) { channel = (ChatChannel)0; if (string.IsNullOrEmpty(message)) { return false; } int num = message.IndexOf("</color>: <color=", StringComparison.OrdinalIgnoreCase); if (num < 0) { return false; } int num2 = num + "</color>: <color=".Length; if (num2 >= message.Length) { return false; } int num3 = message.IndexOf('>', num2); if (num3 < 0) { return false; } int num4 = num2; string token = message.Substring(num4, num3 - num4); string text = NormalizeChannelColorToken(token); if (string.IsNullOrEmpty(text)) { return false; } switch (text) { case "YELLOW": case "#FFFF00": case "#FFD700": channel = (ChatChannel)0; return true; case "#B2EC5D": channel = (ChatChannel)1; return true; case "#FF8A90": channel = (ChatChannel)2; return true; default: return false; } } private static int SkipTimestampPrefix(string msg, int startIndex = 0) { if (string.IsNullOrEmpty(msg) || startIndex >= msg.Length) { return startIndex; } if (msg[startIndex] != '[') { return startIndex; } int num = startIndex + 1; if (num >= msg.Length || !char.IsDigit(msg[num])) { return startIndex; } num++; if (num < msg.Length && char.IsDigit(msg[num])) { num++; } if (num >= msg.Length || msg[num] != ':') { return startIndex; } num++; if (num + 1 >= msg.Length || !char.IsDigit(msg[num]) || !char.IsDigit(msg[num + 1])) { return startIndex; } num += 2; if (num < msg.Length && msg[num] == ' ') { if (num + 2 >= msg.Length || (msg[num + 1] != 'A' && msg[num + 1] != 'a' && msg[num + 1] != 'P' && msg[num + 1] != 'p') || (msg[num + 2] != 'M' && msg[num + 2] != 'm')) { return startIndex; } num += 3; } if (num >= msg.Length || msg[num] != ']') { return startIndex; } num++; if (num < msg.Length && msg[num] == ' ') { num++; } return num; } public static string BuildColoredPrefixFromEnum(ChatChannel ch) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected I4, but got Unknown if (1 == 0) { } string result = (int)ch switch { 0 => "<color=yellow>(G)</color>", 1 => "<color=#B2EC5D>(P)</color>", 2 => "<color=#FF8A90>(Z)</color>", _ => string.Empty, }; if (1 == 0) { } return result; } public static string BuildMessagePrefix(ChatChannel ch) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) string text = null; ConfigEntry<bool> obj = chatTimestamp; if (obj != null && obj.Value) { string text2 = (timestampFormat.Value ? "HH:mm" : "h:mm tt"); text = "[" + DateTime.Now.ToString(text2, CultureInfo.InvariantCulture) + "]"; } string text3 = BuildColoredPrefixFromEnum(ch); if (string.IsNullOrEmpty(text3)) { text3 = null; } if (text == null && text3 == null) { return string.Empty; } if (text != null && text3 != null) { return text + " " + text3 + " "; } return (text ?? text3) + " "; } public static string BuildOocBadge() { return "<color=yellow>[</color><color=#A7FC00>OOC</color><color=yellow>]</color>"; } public static string ExtractRenderedOocBadge(ref string message) { if (!IsOocFeatureEnabled() || string.IsNullOrEmpty(message)) { return string.Empty; } int num = message.IndexOf("</color>: <color=", StringComparison.OrdinalIgnoreCase); if (num < 0) { return string.Empty; } int startIndex = num + "</color>: <color=".Length; int num2 = message.IndexOf('>', startIndex); if (num2 < 0) { return string.Empty; } int startIndex2 = num2 + 1; if (!TryFindLeadingOocToken(message, startIndex2, out var tokenStart, out var tokenLength, out var trailingSpaceStart, out var trailingSpaceLength)) { return string.Empty; } if (trailingSpaceLength > 0) { message = message.Remove(trailingSpaceStart, trailingSpaceLength); } message = message.Remove(tokenStart, tokenLength); return BuildOocBadge(); } public static string CombinePrefixSegments(string prefix, string badge) { bool flag = !string.IsNullOrWhiteSpace(prefix); bool flag2 = !string.IsNullOrWhiteSpace(badge); if (!flag && !flag2) { return string.Empty; } prefix = (flag ? prefix.TrimEnd() : string.Empty); badge = (flag2 ? badge.Trim() : string.Empty); if (!flag) { return badge + " "; } if (!flag2) { return prefix.EndsWith(" ", StringComparison.Ordinal) ? prefix : (prefix + " "); } return prefix + " " + badge + " "; } public static bool LooksPrefixed(string msg) { if (string.IsNullOrEmpty(msg)) { return false; } int num = SkipTimestampPrefix(msg); if (msg.Length - num >= 4 && msg[num] == '(' && (msg[num + 1] == 'G' || msg[num + 1] == 'P' || msg[num + 1] == 'Z') && msg[num + 2] == ')' && msg[num + 3] == ' ') { return true; } if (num < msg.Length && msg.IndexOf("<color", num, StringComparison.OrdinalIgnoreCase) == num) { int num2 = msg.IndexOf('>', num); if (num2 >= 0) { int num3 = msg.IndexOf("</color>", num2 + 1, StringComparison.OrdinalIgnoreCase); if (num3 > num2 + 1) { int num4 = num2 + 1; string text = msg.Substring(num4, num3 - num4); if (text.StartsWith("(G)") || text.StartsWith("(P)") || text.StartsWith("(Z)")) { return true; } } } } return false; } public static string InsertPrefix(string line, string prefix) { if (string.IsNullOrEmpty(prefix) || string.IsNullOrEmpty(line)) { return line; } return prefix + line; } public static string ApplyAsteriskFormatting(string s) { ConfigEntry<bool> obj = asteriskItalic; if (obj == null || !obj.Value || string.IsNullOrEmpty(s) || s.IndexOf('*') < 0) { return s; } StringBuilder stringBuilder = new StringBuilder(s.Length + 16); ReadOnlySpan<char> readOnlySpan = s.AsSpan(); bool flag = false; bool flag2 = false; bool flag3 = false; int num = -1; int num2 = -1; for (int i = 0; i < readOnlySpan.Length; i++) { char c = readOnlySpan[i]; if (c == '<') { flag3 = true; stringBuilder.Append(c); } else if (c == '>' && flag3) { flag3 = false; stringBuilder.Append(c); } else if (c == '\\' && i + 1 < readOnlySpan.Length && readOnlySpan[i + 1] == '*') { stringBuilder.Append('*'); i++; } else if (c == '*' && !flag3) { int j; for (j = i + 1; j < readOnlySpan.Length && readOnlySpan[j] == '*'; j++) { } int num3 = j - i; if (num3 >= 2) { int num4; for (num4 = num3; num4 >= 2; num4 -= 2) { if (flag2) { stringBuilder.Append("</b>"); flag2 = false; num2 = -1; } else { num2 = stringBuilder.Length; stringBuilder.Append("<b>"); flag2 = true; } } if (num4 == 1) { if (flag) { stringBuilder.Append("</i>"); flag = false; num = -1; } else { num = stringBuilder.Length; stringBuilder.Append("<i>"); flag = true; } } } else if (flag) { stringBuilder.Append("</i>"); flag = false; num = -1; } else { num = stringBuilder.Length; stringBuilder.Append("<i>"); flag = true; } i = j - 1; } else { stringBuilder.Append(c); } } if (flag2 && num2 >= 0) { stringBuilder.Remove(num2, 3).Insert(num2, "**"); if (num > num2) { num += -1; } } if (flag && num >= 0) { stringBuilder.Remove(num, 3).Insert(num, "*"); } return stringBuilder.ToString(); } private static bool IsChatSubmitKeyPressed() { return Input.GetKeyDown((KeyCode)13) || Input.GetKeyDown((KeyCode)271); } internal static Transform FindDescendantTransformByName(Transform root, string name) { if ((Object)(object)root == (Object)null || string.IsNullOrEmpty(name)) { return null; } Queue<Transform> queue = new Queue<Transform>(); queue.Enqueue(root); while (queue.Count > 0) { Transform val = queue.Dequeue(); if (!((Object)(object)val == (Object)null)) { if (((Object)val).name == name) { return val; } for (int i = 0; i < val.childCount; i++) { queue.Enqueue(val.GetChild(i)); } } } return null; } internal static T FindDescendantComponentByName<T>(Transform root, string name) where T : Component { Transform val = FindDescendantTransformByName(root, name); return ((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<T>() : default(T); } internal static void ResetLinkPromptRuntimeState() { _pendingChatLinkUrl = null; _chatLinkPromptOpen = false; _chatLinkPromptElement = null; _chatLinkPromptText = null; _chatLinkPromptTextLegacy = null; _chatLinkOpenButton = null; _chatLinkCopyButton = null; _chatLinkCancelButton = null; _chatLinkPromptCanvasGroup = null; if ((Object)(object)_chatLinkPromptRoot != (Object)null && !((object)_chatLinkPromptRoot).Equals((object?)null)) { Object.Destroy((Object)(object)_chatLinkPromptRoot); } _chatLinkPromptRoot = null; } internal static bool PollLinkPromptHotkeys() { if (!_chatLinkPromptOpen) { return false; } if (Input.GetKeyDown((KeyCode)27)) { CancelPendingChatLink(); return true; } if (IsChatSubmitKeyPressed()) { OpenPendingChatLink(); return true; } return false; } internal static void ShowChatLinkPrompt(ChatBehaviourAssets assets, string url) { if (_chatLinkPromptOpen) { return; } if (!TryCanonicalizeUrl(url, out var canonicalUrl)) { ShowErrorPrompt("That link is invalid."); return; } EnsureChatLinkPrompt(assets ?? ChatBehaviourAssets._current); if ((Object)(object)_chatLinkPromptRoot == (Object)null || ((object)_chatLinkPromptRoot).Equals((object?)null)) { ShowErrorPrompt("Chat link prompts are unavailable right now."); return; } _pendingChatLinkUrl = canonicalUrl; SetChatLinkPromptText(canonicalUrl); SetChatLinkPromptVisible(visible: true); EventSystem current = EventSystem.current; if (current != null) { current.SetSelectedGameObject(((Object)(object)_chatLinkOpenButton != (Object)null) ? ((Component)_chatLinkOpenButton).gameObject : null); } } private static void OpenPendingChatLink() { string pendingChatLinkUrl = _pendingChatLinkUrl; HideChatLinkPrompt(); if (!TryCanonicalizeUrl(pendingChatLinkUrl, out var canonicalUrl)) { ShowErrorPrompt("That link is invalid."); } else { Application.OpenURL(canonicalUrl); } } private static void CopyPendingChatLink() { string pendingChatLinkUrl = _pendingChatLinkUrl; HideChatLinkPrompt(); if (!TryCanonicalizeUrl(pendingChatLinkUrl, out var canonicalUrl)) { ShowErrorPrompt("That link is invalid."); return; } try { GUIUtility.systemCopyBuffer = canonicalUrl; PushLocalChatStatus(ChatBehaviour._current, "Link copied to clipboard."); } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogDebug((object)("ChatX could not copy the pending link: " + ex.Message)); } ShowErrorPrompt("Could not copy that link."); } } private static void CancelPendingChatLink() { HideChatLinkPrompt(); } private static void HideChatLinkPrompt() { _pendingChatLinkUrl = null; SetChatLinkPromptVisible(visible: false); EventSystem current = EventSystem.current; if (current != null) { current.SetSelectedGameObject((GameObject)null); } } private static void SetChatLinkPromptVisible(bool visible) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) _chatLinkPromptOpen = visible; if ((Object)(object)_chatLinkPromptRoot == (Object)null || ((object)_chatLinkPromptRoot).Equals((object?)null)) { return; } if ((Object)(object)_chatLinkPromptElement != (Object)null) { _chatLinkPromptRoot.SetActive(true); RectTransform menuElementRect = GetMenuElementRect(_chatLinkPromptElement); if ((Object)(object)menuElementRect != (Object)null) { menuElementRect.anchoredPosition = Vector2.zero; } _chatLinkPromptElement.isEnabled = visible; } if ((Object)(object)_chatLinkPromptCanvasGroup != (Object)null) { _chatLinkPromptCanvasGroup.alpha = (visible ? 1f : 0f); _chatLinkPromptCanvasGroup.blocksRaycasts = visible; _chatLinkPromptCanvasGroup.interactable = visible; } if ((Object)(object)_chatLinkPromptElement == (Object)null) { _chatLinkPromptRoot.SetActive(visible); } if (visible) { Transform transform = _chatLinkPromptRoot.transform; RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null); if (val != null) { ((Transform)val).SetAsLastSibling(); LayoutRebuilder.ForceRebuildLayoutImmediate(val); } } } private static void SetChatLinkPromptText(string canonicalUrl) { string text = "Open this link in your browser?\n" + canonicalUrl; if ((Object)(object)_chatLinkPromptText != (Object)null) { ((TMP_Text)_chatLinkPromptText).text = text; } if ((Object)(object)_chatLinkPromptTextLegacy != (Object)null) { _chatLinkPromptTextLegacy.text = text; } } private static void EnsureChatLinkPrompt(ChatBehaviourAssets assets) { if (!((Object)(object)_chatLinkPromptRoot != (Object)null) || ((object)_chatLinkPromptRoot).Equals((object?)null)) { Transform val = ResolveChatLinkPromptParent(assets); if (!((Object)(object)val == (Object)null)) { int layer = (((Object)(object)assets != (Object)null) ? ((Component)assets).gameObject.layer : ((Component)val).gameObject.layer); TryCreatePromptFromPartyInvite(val, layer); } } } private static bool TryCreatePromptFromPartyInvite(Transform parent, int layer) { //IL_00c4: 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_0118: 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_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0126: 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_029d: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0142: 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_023e: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: 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_025a: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0288: 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_0401: Unknown result type (might be due to invalid IL or missing references) //IL_040b: Expected O, but got Unknown //IL_043c: Unknown result type (might be due to invalid IL or missing references) //IL_0446: Expected O, but got Unknown //IL_0426: Unknown result type (might be due to invalid IL or missing references) //IL_042b: Unknown result type (might be due to invalid IL or missing references) //IL_0431: Expected O, but got Unknown //IL_0477: Unknown result type (might be due to invalid IL or missing references) //IL_0481: Expected O, but got Unknown //IL_0461: Unknown result type (might be due to invalid IL or missing references) //IL_0466: Unknown result type (might be due to invalid IL or missing references) //IL_046c: Expected O, but got Unknown //IL_049c: Unknown result type (might be due to invalid IL or missing references) //IL_04a1: Unknown result type (might be due to invalid IL or missing references) //IL_04a7: Expected O, but got Unknown try { object obj = PartyUiCurrentField?.GetValue(null); object? obj2 = PartyInviteElementField?.GetValue(obj); MenuElement val = (MenuElement)((obj2 is MenuElement) ? obj2 : null); if (obj == null || (Object)(object)val == (Object)null || (Object)(object)((Component)val).gameObject == (Object)null) { return false; } _chatLinkPromptRoot = Object.Instantiate<GameObject>(((Component)val).gameObject, parent, false); ((Object)_chatLinkPromptRoot).name = "ChatX_LinkPrompt"; _chatLinkPromptRoot.SetActive(true); SetLayerRecursive(_chatLinkPromptRoot, layer); RectTransform component = ((Component)val).GetComponent<RectTransform>(); RectTransform component2 = _chatLinkPromptRoot.GetComponent<RectTransform>(); Rect rect; if ((Object)(object)component2 != (Object)null) { Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(720f, 230f); Vector2 val3 = val2; if ((Object)(object)component != (Object)null) { rect = component.rect; val3 = ((Rect)(ref rect)).size; if (val3.x <= 1f || val3.y <= 1f) { val3 = component.sizeDelta; } } if (val3.x <= 1f || val3.y <= 1f) { val3 = val2; } component2.anchorMin = new Vector2(0.5f, 0.5f); component2.anchorMax = new Vector2(0.5f, 0.5f); component2.pivot = (Vector2)(((Object)(object)component != (Object)null) ? component.pivot : new Vector2(0.5f, 0.5f)); component2.sizeDelta = val3 * 2f; component2.anchoredPosition = Vector2.zero; ((Transform)component2).localScale = Vector3.one; ((Transform)component2).localRotation = Quaternion.identity; ((Transform)component2).SetAsLastSibling(); } _chatLinkPromptElement = _chatLinkPromptRoot.GetComponent<MenuElement>(); RectTransform menuElementRect = GetMenuElementRect(_chatLinkPromptElement); if ((Object)(object)menuElementRect != (Object)null) { if ((Object)(object)component2 == (Object)null || menuElementRect != component2) { rect = menuElementRect.rect; Vector2 val4 = ((Rect)(ref rect)).size; if (val4.x <= 1f || val4.y <= 1f) { val4 = menuElementRect.sizeDelta; } if (val4.x > 1f && val4.y > 1f) { menuElementRect.sizeDelta = val4 * 2f; } } menuElementRect.anchoredPosition = Vector2.zero; } _chatLinkPromptCanvasGroup = GetMenuElementCanvasGroup(_chatLinkPromptElement) ?? _chatLinkPromptRoot.GetComponentInChildren<CanvasGroup>(true) ?? _chatLinkPromptRoot.GetComponent<CanvasGroup>(); object? obj3 = PartyInvitePromptField?.GetValue(obj); Component originalComponent = (Component)((obj3 is Component) ? obj3 : null); object? obj4 = PartyAcceptInviteButtonField?.GetValue(obj); Component originalComponent2 = (Component)((obj4 is Component) ? obj4 : null); object? obj5 = PartyDeclineInviteButtonField?.GetValue(obj); Component originalComponent3 = (Component)((obj5 is Component) ? obj5 : null); _chatLinkPromptText = FindClonedComponent<TextMeshProUGUI>(((Component)val).transform, originalComponent, _chatLinkPromptRoot.transform); _chatLinkPromptTextLegacy = FindClonedComponent<Text>(((Component)val).transform, originalComponent, _chatLinkPromptRoot.transform) ?? _chatLinkPromptRoot.GetComponentInChildren<Text>(true); _chatLinkOpenButton = FindClonedComponent<Button>(((Component)val).transform, originalComponent2, _chatLinkPromptRoot.transform); _chatLinkCancelButton = FindClonedComponent<Button>(((Component)val).transform, originalComponent3, _chatLinkPromptRoot.transform); _chatLinkCopyButton = ClonePromptButton(_chatLinkOpenButton, "Button_Copy", layer); if ((Object)(object)_chatLinkOpenButton == (Object)null || (Object)(object)_chatLinkCopyButton == (Object)null || (Object)(object)_chatLinkCancelButton == (Object)null) { Object.Destroy((Object)(object)_chatLinkPromptRoot); ResetLinkPromptRuntimeState(); return false; } _chatLinkOpenButton.onClick = new ButtonClickedEvent(); ButtonClickedEvent onClick = _chatLinkOpenButton.onClick; object obj6 = <>O.<0>__OpenPendingChatLink; if (obj6 == null) { UnityAction val5 = OpenPendingChatLink; <>O.<0>__OpenPendingChatLink = val5; obj6 = (object)val5; } ((UnityEvent)onClick).AddListener((UnityAction)obj6); _chatLinkCopyButton.onClick = new ButtonClickedEvent(); ButtonClickedEvent onClick2 = _chatLinkCopyButton.onClick; object obj7 = <>O.<1>__CopyPendingChatLink; if (obj7 == null) { UnityAction val6 = CopyPendingChatLink; <>O.<1>__CopyPendingChatLink = val6; obj7 = (object)val6; } ((UnityEvent)onClick2).AddListener((UnityAction)obj7); _chatLinkCancelButton.onClick = new ButtonClickedEvent(); ButtonClickedEvent onClick3 = _chatLinkCancelButton.onClick; object obj8 = <>O.<2>__CancelPendingChatLink; if (obj8 == null) { UnityAction val7 = CancelPendingChatLink; <>O.<2>__CancelPendingChatLink = val7; obj8 = (object)val7; } ((UnityEvent)onClick3).AddListener((UnityAction)obj8); ConfigurePromptButtonContent(((Component)_chatLinkOpenButton).gameObject, "Open", PromptButtonIconKind.Confirm, _chatLinkPromptText, iconOnly: true); ConfigurePromptButtonContent(((Component)_chatLinkCopyButton).gameObject, "Copy", PromptButtonIconKind.Copy, _chatLinkPromptText, iconOnly: true); ConfigurePromptButtonContent(((Component)_chatLinkCancelButton).gameObject, "Cancel", PromptButtonIconKind.Cancel, _chatLinkPromptText, iconOnly: true); LayoutPromptButtons(menuElementRect ?? component2, _chatLinkOpenButton, _chatLinkCopyButton, _chatLinkCancelButton); SetChatLinkPromptVisible(visible: false); return true; } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogDebug((object)("ChatX could not clone the party invite modal for link prompts: " + ex.Message)); } ResetLinkPromptRuntimeState(); return false; } } private static Transform ResolveChatLinkPromptParent(ChatBehaviourAssets assets) { Transform val = Resolve(assets) ?? Resolve(ChatBehaviourAssets._current); if ((Object)(object)val != (Object)null) { return val; } try { object obj = PartyUiCurrentField?.GetValue(null); if (obj != null) { object? obj2 = PartyPanelGroupField?.GetValue(obj); CanvasGroup val2 = (CanvasGroup)((obj2 is CanvasGroup) ? obj2 : null); if (val2 != null) { Canvas componentInParent = ((Component)val2).GetComponentInParent<Canvas>(); if ((Object)(object)componentInParent != (Object)null) { return ((Component)componentInParent).transform; } } } } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogDebug((object)("ChatX could not resolve link prompt canvas parent: " + ex.Message)); } } return null; static Transform Resolve(ChatBehaviourAssets candidate) { if ((Object)(object)candidate == (Object)null) { return null; } Canvas val3 = null; if ((Object)(object)candidate._chatText != (Object)null) { val3 = ((Graphic)candidate._chatText).canvas; } if (val3 == null) { val3 = ((Component)candidate).GetComponentInParent<Canvas>(); } if ((Object)(object)val3 != (Object)null) { return ((Component)val3).transform; } return ((Component)candidate).transform; } } private static T FindClonedComponent<T>(Transform originalRoot, Component originalComponent, Transform clonedRoot) where T : Component { if ((Object)(object)originalRoot == (Object)null || (Object)(object)originalComponent == (Object)null || (Object)(object)clonedRoot == (Object)null) { return default(T); } string relativeTransformPath = GetRelativeTransformPath(originalRoot, originalComponent.transform); Transform val = (string.IsNullOrEmpty(relativeTransformPath) ? clonedRoot : clonedRoot.Find(relativeTransformPath)); return ((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<T>() : default(T); } private static string GetRelativeTransformPath(Transform root, Transform target) { if ((Object)(object)root == (Object)null || (Object)(object)target == (Object)null) { return null; } if (root == target) { return string.Empty; } Stack<string> stack = new Stack<string>(); Transform val = target; while ((Object)(object)val != (Object)null && val != root) { stack.Push(((Object)val).name); val = val.parent; } if (val != root) { return null; } return string.Join("/", stack); } private static RectTransform GetMenuElementRect(MenuElement element) { return (RectTransform)(((Object)(object)element != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null); } private static CanvasGroup GetMenuElementCanvasGroup(MenuElement element) { return (CanvasGroup)(((Object)(object)element != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null); } private static Button ClonePromptButton(Button template, string objectName, int layer) { //IL_0079: 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) if ((Object)(object)template == (Object)null || (Object)(object)((Component)template).gameObject == (Object)null) { return null; } Transform parent = ((Component)template).transform.parent; if ((Object)(object)parent == (Object)null) { return null; } GameObject val = Object.Instantiate<GameObject>(((Component)template).gameObject, parent, false); ((Object)val).name = objectName; SetLayerRecursive(val, layer); RectTransform component = val.GetComponent<RectTransform>(); if ((Object)(object)component != (Object)null) { ((Transform)component).localScale = Vector3.one; ((Transform)component).localRotation = Quaternion.identity; } Button component2 = val.GetComponent<Button>(); return ((Object)(object)component2 != (Object)null) ? component2 : val.AddComponent<Button>(); } private static void UpdateButtonLabel(GameObject buttonObject, string label, TextMeshProUGUI fallback) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)buttonObject == (Object)null) { return; } TMP_Text componentInChildren = buttonObject.GetComponentInChildren<TMP_Text>(true); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.text = label; TextMeshProUGUI val = (TextMeshProUGUI)(object)((componentInChildren is TextMeshProUGUI) ? componentInChildren : null); if (val != null) { ApplyPromptTextStyle(val, null, fallback); } return; } Text componentInChildren2 = buttonObject.GetComponentInChildren<Text>(true); if ((Object)(object)componentInChildren2 != (Object)null) { componentInChildren2.text = label; if ((Object)(object)fallback != (Object)null) { ((Graphic)componentInChildren2).color = ((Graphic)fallback).color; componentInChildren2.fontSize = Mathf.RoundToInt(Mathf.Max(18f, ((TMP_Text)fallback).fontSize)); componentInChildren2.alignment = (TextAnchor)4; } } } private static void ConfigurePromptButtonContent(GameObject buttonObject, string label, PromptButtonIconKind iconKind, TextMeshProUGUI fallback, bool iconOnly = false) { //IL_0058: 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) if (!((Object)(object)buttonObject == (Object)null)) { UpdateButtonLabel(buttonObject, iconOnly ? string.Empty : label, fallback); SuppressPromptButtonChildIcons(buttonObject); SetPromptButtonLabelVisible(buttonObject, !iconOnly); if (!iconOnly) { AdjustPromptButtonLabelLayout(buttonObject); } BuildPromptButtonIcon(buttonObject, iconKind, ((Object)(object)fallback != (Object)null) ? ((Graphic)fallback).color : Color.white, iconOnly); } } private static void LayoutPromptButtons(RectTransform hostRect, params Button[] buttons) { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Expected O, but got Unknown //IL_0135: 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_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Unknown result type (might be due to invalid IL or missing references) //IL_031d: Unknown result type (might be due to invalid IL or missing references) //IL_0331: Unknown result type (might be due to invalid IL or missing references) //IL_033e: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)hostRect == (Object)null || buttons == null || buttons.Length == 0) { return; } List<Button> list = new List<Button>(buttons.Length); foreach (Button val in buttons) { if (!((Object)(object)val == (Object)null) && !((object)val).Equals((object?)null)) { list.Add(val); } } if (list.Count == 0) { return; } Transform val2 = ((Transform)hostRect).Find("ChatX_ButtonRow"); RectTransform val3; if ((Object)(object)val2 != (Object)null) { val3 = (RectTransform)(object)((val2 is RectTransform) ? val2 : null); } else { GameObject val4 = new GameObject("ChatX_ButtonRow", new Type[1] { typeof(RectTransform) }); val4.layer = ((Component)hostRect).gameObject.layer; SetLayerRecursive(val4, ((Component)hostRect).gameObject.layer); val3 = val4.GetComponent<RectTransform>(); ((Transform)val3).SetParent((Transform)(object)hostRect, false); } float num = 0f; foreach (Button item in list) { RectTransform component = ((Component)item).GetComponent<RectTransform>(); if (!((Object)(object)component == (Object)null)) { Rect rect = component.rect; float num2 = Mathf.Abs(((Rect)(ref rect)).height); if (num2 <= 1f) { num2 = Mathf.Abs(component.sizeDelta.y); } if (num2 > 1f) { num = num2; break; } } } if (num <= 1f) { num = 44f; } float num3 = Mathf.Max(num * 1.7f, 78f); float num4 = Mathf.Clamp(num * 0.2f, 8f, 14f); float num5 = num3 * (float)list.Count + num4 * (float)(list.Count - 1); val3.anchorMin = new Vector2(0.5f, 0f); val3.anchorMax = new Vector2(0.5f, 0f); val3.pivot = new Vector2(0.5f, 0f); val3.sizeDelta = new Vector2(num5, num); val3.anchoredPosition = new Vector2(0f, Mathf.Clamp(num * 0.5f, 18f, 30f)); ((Transform)val3).SetAsLastSibling(); for (int j = 0; j < list.Count; j++) { Button val5 = list[j]; RectTransform component2 = ((Component)val5).GetComponent<RectTransform>(); if (!((Object)(object)component2 == (Object)null)) { ((Component)val5).transform.SetParent((Transform)(object)val3, false); float num6 = 0f - (num5 - num3) * 0.5f; float num7 = num6 + (float)j * (num3 + num4); component2.anchorMin = new Vector2(0.5f, 0.5f); component2.anchorMax = new Vector2(0.5f, 0.5f); component2.pivot = new Vector2(0.5f, 0.5f); component2.sizeDelta = new Vector2(num3, num); component2.anchoredPosition = new Vector2(num7, 0f); ((Transform)component2).localScale = Vector3.one; ((Transform)component2).localRotation = Quaternion.identity; LayoutElement component3 = ((Component)val5).GetComponent<LayoutElement>(); if ((Object)(object)component3 != (Object)null) { component3.ignoreLayout = true; } } } LayoutRebuilder.ForceRebuildLayoutImmediate(val3); LayoutRebuilder.ForceRebuildLayoutImmediate(hostRect); } private static void SetPromptButtonLabelVisible(GameObject buttonObject, bool visible) { if ((Object)(object)buttonObject == (Object)null) { return; } TMP_Text[] componentsInChildren = buttonObject.GetComponentsInChildren<TMP_Text>(true); foreach (TMP_Text val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !(((Object)((Component)val).gameObject).name == "ChatX_Icon")) { val.text = (visible ? val.text : string.Empty); ((Behaviour)val).enabled = visible; } } Text[] componentsInChildren2 = buttonObject.GetComponentsInChildren<Text>(true); foreach (Text val2 in componentsInChildren2) { if (!((Object)(object)val2 == (Object)null) && !(((Object)((Component)val2).gameObject).name == "ChatX_Icon")) { val2.text = (visible ? val2.text : string.Empty); ((Behaviour)val2).enabled = visible; } } } private static void SuppressPromptButtonChildIcons(GameObject buttonObject) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00df: 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) if ((Object)(object)buttonObject == (Object)null) { return; } RectTransform component = buttonObject.GetComponent<RectTransform>(); float num = 0f; Rect rect; if ((Object)(object)component != (Object)null) { rect = component.rect; Vector2 size = ((Rect)(ref rect)).size; num = Mathf.Abs(size.x * size.y); } Image component2 = buttonObject.GetComponent<Image>(); Image[] componentsInChildren = buttonObject.GetComponentsInChildren<Image>(true); foreach (Image val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)component2) && !((Object)(object)((Component)val).transform.parent != (Object)(object)buttonObject.transform)) { RectTransform rectTransform = ((Graphic)val).rectTransform; float num2; if (!((Object)(object)rectTransform != (Object)null)) { num2 = 0f; } else { rect = rectTransform.rect; float width = ((Rect)(ref rect)).width; rect = rectTransform.rect; num2 = Mathf.Abs(width * ((Rect)(ref rect)).height); } float num3 = num2; if (!(num > 0f) || !(num3 >= num * 0.7f)) { ((Behaviour)val).enabled = false; ((Graphic)val).raycastTarget = false; } } } } private static void AdjustPromptButtonLabelLayout(GameObject buttonObject) { //IL_006d: 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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)buttonObject == (Object)null) { return; } TextMeshProUGUI[] componentsInChildren = buttonObject.GetComponentsInChildren<TextMeshProUGUI>(true); foreach (TextMeshProUGUI val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !(((Object)((Component)val).gameObject).name == "ChatX_Icon")) { RectTransform rectTransform = ((TMP_Text)val).rectTransform; if ((Object)(object)rectTransform != (Object)null) { rectTransform.offsetMin = new Vector2(Mathf.Max(rectTransform.offsetMin.x, 34f), rectTransform.offsetMin.y); rectTransform.offsetMax = new Vector2(Mathf.Min(rectTransform.offsetMax.x, -8f), rectTransform.offsetMax.y); } ((TMP_Text)val).alignment = (TextAlignmentOptions)4097; return; } } Text[] componentsInChildren2 = buttonObject.GetComponentsInChildren<Text>(true); foreach (Text val2 in componentsInChildren2) { if (!((Object)(object)val2 == (Object)null) && !(((Object)((Component)val2).gameObject).name == "ChatX_Icon")) { Transform transform = ((Component)val2).transform; RectTransform val3 = (RectTransform)(object)((transform is RectTransform) ? transform : null); if (val3 != null) { val3.offsetMin = new Vector2(Mathf.Max(val3.offsetMin.x, 34f), val3.offsetMin.y); val3.offsetMax = new Vector2(Mathf.Min(val3.offsetMax.x, -8f), val3.offsetMax.y); } val2.alignment = (TextAnchor)3; break; } } } private static void BuildPromptButtonIcon(GameObject buttonObject, PromptButtonIconKind iconKind, Color baseColor, bool centered = false) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown //IL_00cf: 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_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: 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_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)buttonObject == (Object)null) { return; } Transform val = buttonObject.transform.Find("ChatX_Icon"); GameObject val2; if ((Object)(object)val != (Object)null) { val2 = ((Component)val).gameObject; for (int num = val2.transform.childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)val2.transform.GetChild(num)).gameObject); } } else { val2 = new GameObject("ChatX_Icon", new Type[1] { typeof(RectTransform) }); SetLayerRecursive(val2, buttonObject.layer); RectTransform component = val2.GetComponent<RectTransform>(); ((Transform)component).SetParent(buttonObject.transform, false); } RectTransform component2 = val2.GetComponent<RectTransform>(); component2.anchorMin = new Vector2(0.5f, 0.5f); component2.anchorMax = new Vector2(0.5f, 0.5f); component2.pivot = new Vector2(0.5f, 0.5f); component2.sizeDelta = new Vector2(24f, 24f); component2.anchoredPosition = (Vector2)(centered ? Vector2.zero : new Vector2(-18f, 0f)); ((Transform)component2).SetAsFirstSibling(); Color val3 = baseColor; if (iconKind == PromptButtonIconKind.Confirm) { ((Color)(ref val3))..ctor(Mathf.Clamp01(baseColor.r + 0.08f), Mathf.Clamp01(baseColor.g + 0.12f), Mathf.Clamp01(baseColor.b), baseColor.a); } switch (iconKind) { case PromptButtonIconKind.Confirm: CreatePromptIconStroke(val2.transform, new Vector2(5f, 12f), new Vector2(-5.5f, -3.5f), 42f, val3); CreatePromptIconStroke(val2.transform, new Vector2(5f, 22f), new Vector2(4.5f, 1.5f), -44f, val3); break; case PromptButtonIconKind.Copy: CreatePromptIconOutline(val2.transform, new Vector2(10f, 12f), new Vector2(-2.5f, 2.5f), 2f, new Color(val3.r, val3.g, val3.b, val3.a * 0.72f)); CreatePromptIconOutline(val2.transform, new Vector2(10f, 12f), new Vector2(2.5f, -1.5f), 2f, val3); break; case PromptButtonIconKind.Cancel: CreatePromptIconStroke(val2.transform, new Vector2(5f, 22f), Vector2.zero, 45f, val3); CreatePromptIconStroke(val2.transform, new Vector2(5f, 22f), Vector2.zero, -45f, val3); break; } } private static void CreatePromptIconOutline(Transform parent, Vector2 size, Vector2 position, float thickness, Color color) { //IL_0016: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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_006f: 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) //IL_007b: 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_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009b: 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_00a6: 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_00bc: 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: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: 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) if (!((Object)(object)parent == (Object)null)) { float num = Mathf.Max(0f, (size.x - thickness) * 0.5f); float num2 = Mathf.Max(0f, (size.y - thickness) * 0.5f); CreatePromptIconStroke(parent, new Vector2(size.x, thickness), position + new Vector2(0f, num2), 0f, color); CreatePromptIconStroke(parent, new Vector2(size.x, thickness), position - new Vector2(0f, num2), 0f, color); CreatePromptIconStroke(parent, new Vector2(thickness, size.y), position + new Vector2(num, 0f), 0f, color); CreatePromptIconStroke(parent, new Vector2(thickness, size.y), position - new Vector2(num, 0f), 0f, color); } } private static void CreatePromptIconStroke(Transform parent, Vector2 size, Vector2 position, float rotation, Color color) { //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) //IL_004e: Expected O, but got Unknown //IL_0069: 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) //IL_0095: 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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)parent == (Object)null)) { GameObject val = new GameObject("Stroke", new Type[2] { typeof(RectTransform), typeof(Image) }) { layer = ((Component)parent).gameObject.layer }; RectTransform component = val.GetComponent<RectTransform>(); ((Transform)component).SetParent(parent, false); component.anchorMin = new Vector2(0.5f, 0.5f); component.anchorMax = new Vector2(0.5f, 0.5f); component.pivot = new Vector2(0.5f, 0.5f); component.sizeDelta = size; component.anchoredPosition = position; ((Transform)component).localRotation = Quaternion.Euler(0f, 0f, rotation); Image component2 = val.GetComponent<Image>(); ((Graphic)component2).color = color; ((Graphic)component2).raycastTarget = false; } } private static void ApplyPromptTextStyle(TextMeshProUGUI target, Component template, TextMeshProUGUI fallback) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: 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_0129: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null) { return; } TMP_Text val = (TMP_Text)(object)((template is TMP_Text) ? template : null); if (val != null) { ((TMP_Text)target).font = val.font; ((TMP_Text)target).fontStyle = val.fontStyle; ((TMP_Text)target).fontMaterial = val.fontMaterial; ((Graphic)target).color = ((Graphic)val).color; ((TMP_Text)target).fontSize = val.fontSize; } else { Text val2 = (Text)(object)((template is Text) ? template : null); if (val2 != null) { if ((Object)(object)TMP_Settings.defaultFontAsset != (Object)null) { ((TMP_Text)target).font = TMP_Settings.defaultFontAsset; } ((Graphic)target).color = ((Graphic)val2).color; ((TMP_Text)target).fontSize = val2.fontSize; } else if ((Object)(object)fallback != (Object)null) { ((TMP_Text)target).font = ((TMP_Text)fallback).font; ((TMP_Text)target).fontStyle = ((TMP_Text)fallback).fontStyle; ((TMP_Text)target).fontMaterial = ((TMP_Text)fallback).fontMaterial; ((Graphic)target).color = ((Graphic)fallback).color; ((TMP_Text)target).fontSize = ((TMP_Text)fallback).fontSize; } else if ((Object)(object)TMP_Settings.defaultFontAsset != (Object)null) { ((TMP_Text)target).font = TMP_Settings.defaultFontAsset; ((Graphic)target).color = Color.white; ((TMP_Text)target).fontSize = 24f; } } ((TMP_Text)target).alignment = (TextAlignmentOptions)514; ((TMP_Text)target).enableWordWrapping = true; ((TMP_Text)target).overflowMode = (TextOverflowModes)0; ((Graphic)target).raycastTarget = false; } internal static void EnsureChatLinkUi(ChatBehaviourAssets assets) { if (!Object.op_Implicit((Object)(object)assets) || (Object)(object)assets._chatText == (Object)null) { return; } ScrollRect componentInParent = ((Component)assets._chatText).GetComponentInParent<ScrollRect>(); if ((Object)(object)componentInParent == (Object)null) { return; } GameObject val = ResolveChatLinkOverlay(componentInParent, assets._chatText); if (!((Object)(object)val == (Object)null)) { ChatLinkClickHandler chatLinkClickHandler = val.GetComponent<ChatLinkClickHandler>(); if ((Object)(object)chatLinkClickHandler == (Object)null) { chatLinkClickHandler = val.AddComponent<ChatLinkClickHandler>(); } chatLinkClickHandler.Bind(assets, componentInParent, assets._chatText); ((Graphic)assets._chatText).raycastTarget = false; } } private static GameObject ResolveChatLinkOverlay(ScrollRect scrollRect, TextMeshProUGUI chatText) { //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_00dd: Expected O, but got Unknown //IL_0103: 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_011d: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0137: 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_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)scrollRect == (Object)null) { return null; } RectTransform val = scrollRect.viewport; if ((Object)(object)val == (Object)null && (Object)(object)chatText != (Object)null) { Transform parent = ((TMP_Text)chatText).transform.parent; val = (RectTransform)(object)((parent is RectTransform) ? parent : null); } if ((Object)(object)val == (Object)null) { val = ((Component)scrollRect).GetComponent<RectTransform>(); } if ((Object)(object)val == (Object)null) { return null; } Transform val2 = ((Transform)val).Find("ChatX_LinkClickOverlay"); GameObject val3 = (((Object)(object)val2 != (Object)null) ? ((Component)val2).gameObject : null); if ((Object)(object)val3 == (Object)null) { val3 = new GameObject("ChatX_LinkClickOverlay", new Type[2] { typeof(RectTransform), typeof(Image) }) { layer = ((Component)val).gameObject.layer }; SetLayerRecursive(val3, ((Component)val).gameObject.layer); RectTransform component = val3.GetComponent<RectTransform>(); ((Transform)component).SetParent((Transform)(object)val, false); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.offsetMin = Vector2.zero; component.offsetMax = Vector2.zero; ((Transform)component).localScale = Vector3.one; } Image val4 = val3.GetComponent<Image>(); if ((Object)(object)val4 == (Object)null) { val4 = val3.AddComponent<Image>(); } ((Graphic)val4).color = new Color(0f, 0f, 0f, 0f); ((Graphic)val4).raycastTarget = true; ((MaskableGraphic)val4).maskable = true; RectTransform component2 = val3.GetComponent<RectTransform>(); component2.anchorMin = Vector2.zero; component2.anchorMax = Vector2.one; component2.offsetMin = Vector2.zero; component2.offsetMax = Vector2.zero; ((Transform)component2).localScale = Vector3.one; ((Transform)component2).SetAsLastSibling(); return val3; } private static string ProtectChatLinks(string message, out List<ProtectedChatLink> protectedLinks) { protectedLinks = null; if (string.IsNullOrEmpty(message)) { return message; } StringBuilder stringBuilder = new StringBuilder(message.Length); int num = 0; int num2 = -1; bool flag = false; for (int i = 0; i < message.Length; i++) { char c = message[i]; if (!flag && c == '<') { AppendProtectedPlainText(stringBuilder, message, num, i - num, ref protectedLinks); flag = true; num2 = i; } else if (flag && c == '>') { stringBuilder.Append(message, num2, i - num2 + 1); flag = false; num = i + 1; } } if (flag && num2 >= 0) { stringBuilder.Append(message, num2, message.Length - num2); } else if (num < message.Length) { AppendProtectedPlainText(stringBuilder, message, num, message.Length - num, ref protectedLinks); } return (protectedLinks == null || protectedLinks.Count == 0) ? message : stringBuilder.ToString(); } private static string RestoreProtectedChatLinks(string message, List<ProtectedChatLink> protectedLinks) { if (string.IsNullOrEmpty(message) || protectedLinks == null || protectedLinks.Count == 0) { return message; } foreach (ProtectedChatLink protectedLink in protectedLinks) { if (protectedLink != null && !string.IsNullOrEmpty(protectedLink.Token)) { string newValue = "<link=\"" + protectedLink.CanonicalUrl + "\"><u>" + protectedLink.DisplayText + "</u></link>"; message = message.Replace(protectedLink.Token, newValue, StringComparison.Ordinal); } } return message; } private static void AppendProtectedPlainText(StringBuilder output, string source, int startIndex, int length, ref List<ProtectedChatLink> protectedLinks) { if (length <= 0) { return; } string text = source.Substring(startIndex, length); int num = 0; foreach (Match item in UrlRegex.Matches(text)) { if (!item.Success) { continue; } output.Append(text, num, item.Index - num); string candidate = item.Value; string value = TrimTrailingUrlPunctuation(ref candidate); if (!TryCanonicalizeUrl(candidate, out var canonicalUrl)) { output.Append(item.Value); num = item.Index + item.Length; continue; } if (protectedLinks == null) { protectedLinks = new List<ProtectedChatLink>(); } string text2 = $"CHATX_LINK_TOKEN_{protectedLinks.Count}_"; protectedLinks.Add(new ProtectedChatLink { Token = text2, DisplayText = candidate, CanonicalUrl = canonicalUrl }); output.Append(text2); if (!string.IsNullOrEmpty(value)) { output.Append(value); } num = item.Index + item.Length; } if (num < text.Length) { output.Append(text, num, text.Length - num); } } private static string TrimTrailingUrlPunctuation(ref string candidate) { if (string.IsNullOrEmpty(candidate)) { return string.Empty; } int num = candidate.Length; while (num > 0 && IsTrimmedUrlPunctuation(candidate[num - 1])) { num--; } string text; if (num >= candidate.Length) { text = string.Empty; } else { string text2 = candidate; int num2 = num; text = text2.Substring(num2, text2.Length - num2); } string result = text; candidate = candidate.Substring(0, num); return result; } private static bool IsTrimmedUrlPunctuation(char c) { if (1 == 0) { } bool result; switch (c) { case '!': case '"': case '\'': case ')': case ',': case '.': case ':': case ';': case '?': case ']': case '}': result = true; break; default: result = false; break; } if (1 == 0) { } return result; } private static bool TryCanonicalizeUrl(string value, out string canonicalUrl) { canonicalUrl = null; if (string.IsNullOrWhiteSpace(value)) { return false; } string uriString = (value.StartsWith("www.", StringComparison.OrdinalIgnoreCase) ? ("https://" + value) : value); if (!Uri.TryCreate(uriString, UriKind.Absolute, out Uri result)) { return false; } if (!string.Equals(result.Scheme, Uri.UriSchemeHttp, StringComparison.OrdinalIgnoreCase) && !string.Equals(result.Scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase)) { return false; } canonicalUrl = result.AbsoluteUri; return true; } private static void SetLayerRecursive(GameObject root, int layer) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown if ((Object)(object)root == (Object)null) { return; } root.layer = layer; foreach (Transform item in root.transform) { Transform val = item; SetLayerRecursive(((Component)val).gameObject, layer); } } private static ChatScrollbarState GetScrollbarState(ChatBehaviourAssets assets) { if (!Object.op_Implicit((Object)(object)assets)) { return null; } if (!_scrollbarStates.TryGetValue(assets, out var value)) { value = new ChatScrollbarState(); _scrollbarStates.Add(assets, value); } if ((Object)(object)value.ScrollRect == (Object)null) { value.ScrollRect = TryGetChatScrollRect(assets); } if ((Object)(object)value.Scrollbar == (Object)null || (Object)(object)value.ScrollbarObject == (Object)null || (Object)(object)value.ScrollbarComponent == (Object)null) { CanvasGroup val = TryGetScrollbarGroup(assets, value); if ((Object)(object)val != (Object)null) { value.Scrollbar = val; } } if ((Object)(object)value.ChatContainer == (Object)null) { value.ChatContainer = ResolveChatContainer(assets); } return value; } internal static void RegisterScrollbarTargets(ChatBehaviourAssets assets, ScrollRect chatScrollRect) { if (!Object.op_Implicit((Object)(object)assets)) { return; } ChatScrollbarState orCreateValue = _scrollbarStates.GetOrCreateValue(assets); if (!((Object)(object)chatScrollRect != (Object)null)) { return; } orCreateValue.ScrollRect = chatScrollRect; Scrollbar verticalScrollbar = chatScrollRect.verticalScrollbar; if ((Object)(object)verticalScrollbar != (Object)null) { orCreateValue.ScrollbarComponent = verticalScrollbar; orCreateValue.ScrollbarObject = ((Component)verticalScrollbar).gameObject; if ((Object)(object)orCreateValue.Scrollbar == (Object)null) { orCreateValue.Scrollbar = ((Component)verticalScrollbar).GetComponent<CanvasGroup>() ?? orCreateValue.ScrollbarObject.AddComponent<CanvasGroup>(); } } } private static ScrollRect TryGetChatScrollRect(ChatBehaviourAssets assets) { TextMeshProUGUI val = assets?._chatText; if (!Object.op_Implicit((Object)(object)val)) { return null; } try { return ((Component)val).GetComponentInParent<ScrollRect>(); } catch { return null; } } private static GameObject ResolveChatContainer(ChatBehaviourAssets assets) { if (!Object.op_Implicit((Object)(object)assets)) { return null; } if ((Object)(object)assets._chatboxTextGroup != (Object)null) { return ((Component)assets._chatboxTextGroup).gameObject; } Transform val = FindDescendantTransformByName(((Component)assets).transform, "_chatbox_textField"); if ((Object)(object)val != (Object)null) { return ((Component)val).gameObject; } TextMeshProUGUI chatText = assets._chatText; return ((Object)(object)chatText != (Object)null) ? ((Component)chatText).gameObject : null; } private static bool ShouldHoldChatForExternalUI() { DialogManager current = DialogManager._current; if (Object.op_Implicit((Object)(object)current) && current._isDialogEnabled) { _dialogSuppressed = true; return true; } if (_dialogSuppressed) { _dialogSuppressed = false; pendingRestore = true; } return false; } private static void ResetChatFocus() { ChatBehaviour current = ChatBehaviour._current; if (!Object.op_Implicit((Object)(object)current)) { return; } current._focusedInChat = false; ChatInputResolver.TryGet(current._chatAssets)?.Deactivate(); if (ChatInputBufferField != null) { try { ChatInputBufferField.SetValue(current, 0f); } catch { } } else if (!_loggedMissingInputBufferField) { _loggedMissingInputBufferField = true; ManualLogSource log = Log; if (log != null) { log.LogWarning((object)"ChatX could not resolve ChatBehaviour._inputBuffer. Hidden-chat focus restoration may be limited."); } } current.Display_Chat(true); current._textFadeTimer = Mathf.Max(current._textFadeTimer, 1f); current._logicFadeTimer = Mathf.Max(current._logicFadeTimer, 1f); if (Object.op_Implicit((Object)(object)current._chatAssets)) { CanvasGroup generalCanvasGroup = current._chatAssets._generalCanvasGroup; if (Object.op_Implicit((Object)(object)generalCanvasGroup)) { generalCanvasGroup.alpha = 1f; generalCanvasGroup.blocksRaycasts = true; generalCanvasGroup.interactable = true; } } } internal static void ResetUiRuntimeState() { _dialogSuppressed = false; pendingRestore = false; _chatWasHidden = false; _loggedMissingInputBufferField = false; ChatWindowResizer.Reset(); } private static void SyncChatVisibility(ChatBehaviourAssets assets, ChatScrollbarState state, bool chatHidden, bool allFaded) { if (state == null) { return; } GameObject val = state.ChatContainer; if ((Object)(object)val == (Object)null) { val = (state.ChatContainer = ResolveChatContainer(assets)); } if ((Object)(object)val != (Object)null) { if (chatHidden) { if (!state.CachedChatContainerActive.HasValue) { state.CachedChatContainerActive = val.activeSelf; } if (val.activeSelf) { val.SetActive(false); } } else if (state.CachedChatContainerActive.HasValue) { bool value = state.CachedChatContainerActive.Value; state.CachedChatContainerActive = null; if (val.activeSelf != value) { val.SetActive(value); } } } GameObject val2 = assets?._chatChannelDockObject; if ((Object)(object)val2 != (Object)null) { if (chatHidden) { if (!state.CachedChannelDockActive.HasValue) { state.CachedChannelDockActive = val2.activeSelf; } if (val2.activeSelf) { val2.SetActive(false); } } else if (state.CachedChannelDockActive.HasValue) { bool value2 = state.CachedChannelDockActive.Value; state.CachedChannelDockActive = null; if (val2.activeSelf != value2) { val2.SetActive(value2); } } } CanvasGroup val3 = assets?._generalCanvasGroup; if ((Object)(object)val3 != (Object)null) { bool interactable = (val3.blocksRaycasts = !allFaded); val3.interactable = interactable; } if ((Object)(object)state.ScrollRect != (Object)null) { bool enabled = !allFaded; ((Behaviour)state.ScrollRect).enabled = enabled; } } private static CanvasGroup TryGetScrollbarGroup(ChatBehaviourAssets assets, ChatScrollbarState state) { if (state == null) { return null; } ScrollRect val = (state.ScrollRect = state.ScrollRect ?? TryGetChatScrollRect(assets)); if ((Object)(object)val == (Object)null) { return null; } Scrollbar verticalScrollbar = val.verticalScrollbar; if ((Object)(object)verticalScrollbar == (Object)null) { return null; } state.ScrollbarComponent = verticalScrollbar; state.ScrollbarObject = ((Component)verticalScrollbar).gameObject; CanvasGroup val2 = ((Component)verticalScrollbar).GetComponent<CanvasGroup>(); if ((Object)(object)val2 == (Object)null) { val2 = state.ScrollbarObject.AddComponent<CanvasGroup>(); } return val2; } private static void UpdateScrollbarState(ChatBehaviourAssets assets, ChatScrollbarState state, bool chatHidden, float visualAlpha, bool transparentOverride, bool allFaded) { if (state == null) { return; } if ((Object)(object)state.ScrollRect == (Object)null) { state.ScrollRect = TryGetChatScrollRect(assets); } if ((Object)(object)state.ScrollRect == (Object)null) { return; } if ((Object)(object)state.Scrollbar == (Object)null || (Object)(object)state.ScrollbarObject == (Object)null || (Object)(object)state.ScrollbarComponent == (Object)null) { state.Scrollbar = TryGetScrollbarGroup(assets, state); if ((Object)(object)state.ScrollRect == (Object)null) { return; } } bool flag = !chatHidden && !allFaded && ShouldShowScrollbar(state); float num = (transparentOverride ? 0f : visualAlpha); if ((Object)(object)state.Scrollbar != (Object)null) { state.Scrollbar.alpha = (flag ? num : 0f); state.Scrollbar.blocksRaycasts = flag; state.Scrollbar.interactable = flag; } if ((Object)(object)state.ScrollbarComponent != (Object)null) { ((Selectable)state.ScrollbarComponent).interactable = flag; } } private static void UpdateEffectiveAlpha(ref float alpha, ref bool sawNonZero, float candidate) { if (candidate > 0.001f) { sawNonZero = true; alpha = Mathf.Min(alpha, candidate); } } private static bool HasExternalHudOverlay(ChatBehaviourAssets assets) { TextMeshProUGUI val = assets?._triggerMessageText; return (Object)(object)val != (Object)null && ((Behaviour)val).enabled && ((Component)val).gameObject.activeInHierarchy && !string.IsNullOrWhiteSpace(((TMP_Text)val).text); } private static bool ShouldShowScrollbar(ChatScrollbarState state) { //IL_0066: 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_0076: 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_0098: Unknown result type (might be due to invalid IL or missing references) ScrollRect val = state?.ScrollRect; if ((Object)(object)val == (Object)null) { return false; } RectTransform content = val.content; RectTransform val2 = (((Object)(object)val.viewport != (Object)null) ? val.viewport : ((Component)val).GetComponent<RectTransform>()); if ((Object)(object)content == (Object)null || (Object)(object)val2 == (Object)null) { return false; } Rect rect = content.rect; float num = ((Rect)(ref rect)).height; rect = val2.rect; float height = ((Rect)(ref rect)).height; if (num <= 0f) { num = content.sizeDelta.y; } return num - height > 1f; } internal static void ApplyOpacityCap(ChatBehaviourAssets assets, bool force = false) { if (!Object.op_Implicit((Object)(object)assets)) { return; } bool flag = ShouldHoldChatForExternalUI(); bool flag2 = _chatHidden || flag; bool chatWasHidden = _chatWasHidden; _chatWasHidden = flag2; if (chatWasHidden && !flag2) { pendingRestore = true; } bool flag3 = pendingRestore && !flag2; if (flag3) { pendingRestore = false; } float num = (flag2 ? 0f : Mathf.Clamp01(chatOpacity?.Value ?? 1f)); float alpha = num; bool sawNonZero = false; CanvasGroup generalCanvasGroup = assets._generalCanvasGroup; float num2 = (flag2 ? 0f : 1f); CanvasGroup[] chatTextGroups = assets._chatTextGroups; if (chatTextGroups != null) { foreach (CanvasGroup val in chatTextGroups) { if (Object.op_Implicit((Object)(object)val)) { float alpha2 = val.alpha; float num3 = (flag2 ? 0f : (flag3 ? num : Mathf.Min(alpha2, num))); if (force || flag3 || !Mathf.Approximately(alpha2, num3)) { val.alpha = num3; } UpdateEffectiveAlpha(ref alpha, ref sawNonZero, val.alpha); } } } if (Object.op_Implicit((Object)(object)assets._chatboxTextGroup)) { float alpha3 = assets._chatboxTextGroup.alpha; float num4 = (flag2 ? 0f : (flag3 ? num : Mathf.Min(alpha3, num))); if (force || flag3 || !Mathf.Approximately(alpha3, num4)) { assets._chatboxTextGroup.alpha = num4; } UpdateEffectiveAlpha(ref alpha, ref sawNonZero, assets._chatboxTextGroup.alpha); } if (Object.op_Implicit((Object)(object)assets._gameLogicGroup)) { float alpha4 = assets._gameLogicGroup.alpha; float num5 = (flag2 ? 0f : (flag3 ? num : Mathf.Min(alpha4, num))); if (force || flag3 || !Mathf.Approximately(alpha4, num5)) { assets._gameLogicGroup.alpha = num5; } UpdateEffectiveAlpha(ref alpha, ref sawNonZero, assets._gameLogicGroup.alpha); } bool flag4 = flag2 || !sawNonZero; bool flag5 = HasExternalHudOverlay(assets); if (flag4) { alpha = 0f; } alpha = Mathf.Clamp01(alpha); bool transparentOverride = transparentScrollbar?.Value ?? false; if (Object.op_Implicit((Object)(object)generalCanvasGroup)) { float num6 = (flag5 ? 1f : (flag4 ? 0f : num2)); if (force || !Mathf.Approximately(generalCanvasGroup.alpha, num6)) { generalCanvasGroup.alpha = num6; } bool flag6 = !flag4; if (generalCanvasGroup.blocksRaycasts != flag6) { generalCanvasGroup.blocksRaycasts = flag6; } if (generalCanvasGroup.interactable != flag6) { generalCanvasGroup.interactable = flag6; } } ChatScrollbarState scrollbarState = GetScrollbarState(assets); if (scrollbarState != null) { UpdateScrollbarState(assets, scrollbarState, flag2, alpha, transparentOverride, flag4); SyncChatVisibility(assets, scrollbarState, flag2, flag4); } } public static void ClearChatNow() { ChatBehaviour val = Player._mainPlayer?._chatBehaviour; ChatBehaviourAssets val2 = val?._chatAssets; if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val2)) { val._chatMessages?.Clear(); if (Object.op_Implicit((Object)(object)val2._chatText)) { ((TMP_Text)val2._chatText).text = string.Empty; } ApplyOpacityCap(val2); } } public static void ClearGameFeedNow() { ChatBehaviour val = Player._mainPlayer?._chatBehaviour; ChatBehaviourAssets val2 = val?._chatAssets; if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val2)) { val._gameLogicMessages?.Clear(); if (Object.op_Implicit((Object)(object)val2._gameLogicText)) { ((TMP_Text)val2._gameLogicText).text = string.Empty; } ApplyOpacityCap(val2); } } public static void ClearAllNow() { ClearChatNow(); ClearGameFeedNow(); } private static void TryHandleHotkeys() { //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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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_0075: Unknown result type (might be due to invalid IL or missing references) Player mainPlayer = Player._mainPlayer; if (Object.op_Implicit((Object)(object)mainPlayer)) { bool flag = ChatInputResolver.TryGetCurrent()?.IsFocused ?? false; ConfigEntry<KeyCode> obj = clearChatKey; KeyCode val = (KeyCode)((obj != null) ? ((int)obj.Value) : 0); if ((int)val != 0 && !flag && Input.GetKeyDown(val)) { ClearAllNow(); } ConfigEntry<KeyCode> obj2 = toggleChatVisibilityKey; KeyCode val2 = (KeyCode)((obj2 != null) ? ((int)obj2.Value) : 0); if ((int)val2 != 0 && !flag && Input.GetKeyDown(val2)) { _chatHidden = !_chatHidden; ChatBehaviourAssets assets = mainPlayer?._chatBehaviour?._chatAssets ?? ChatBehaviourAssets._current; ApplyOpacityCap(assets, force: true); } } } private static bool ShouldPushGameFeed() { return pushGameMessage?.Value ?? false; } private static string StripRichTextTags(string message) { if (string.IsNullOrEmpty(message)) { return message; } StringBuilder stringBuilder = new StringBuilder(message.Length); bool flag = false; foreach (char c in message) { if (c == '<') { flag = true; } else if (c == '>' && flag) { flag = false; } else if (!flag) { stringBuilder.Append(c); } } return stringBuilder.ToString(); } internal static void RouteWaypointAttuneMessage(ChatBehaviour chat, string message) { if (!ShouldPushGameFeed()) { if (chat != null) { chat.New_ChatMessage(message); } } else if (Object.op_Implicit((Object)(object)chat) && !string.IsNullOrEmpty(message)) { PushGameFeedMessage(chat, StripRichTextTags(message)); } } internal static void PushGameFeedMessage(ChatBehaviour chat, string message) { if (Object.op_Implicit((Object)(object)chat) && !string.IsNullOrEmpty(message)) { if (ShouldPushGameFeed()) { chat.Init_GameLogicMessage(message); } else { chat.New_ChatMessage(message); } } } internal static void PushTargetedGameFeedMessage(ChatBehaviour chat, string message) { if (Object.op_Implicit((Object)(object)chat) && !string.IsNullOrEmpty(message)) { if (ShouldPushGameFeed()) { chat.Target_GameLogicMessage(message); } else { chat.Target_RecieveMessage(message); } } } private void Awake() { //IL_001e: Unknown result