using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.UI; using UnityEngine.UI.ProceduralImage; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("PeakTextChatCN")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("PeakTextChatCN")] [assembly: AssemblyTitle("PeakTextChatCN")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace PeakTextChatCN { [BepInPlugin("com.github.peaktextchatcn", "文本聊天", "1.0.1")] public class Plugin : BaseUnityPlugin { internal static class PluginInfo { public const string PLUGIN_GUID = "com.github.peaktextchatcn"; public const string PLUGIN_NAME = "文本聊天"; public const string PLUGIN_VERSION = "1.0.1"; } internal static ConfigEntry ConfigEnabled; internal static ConfigEntry ConfigChatKey; internal static ConfigEntry ConfigChatX; internal static ConfigEntry ConfigChatY; internal static ConfigEntry ConfigChatW; internal static ConfigEntry ConfigChatH; internal static ConfigEntry ConfigChatFontSize; internal static ConfigEntry ConfigChatBgAlpha; internal static ConfigEntry ConfigChatBoxHideDelay; internal static ConfigEntry ConfigContinuousMode; private Harmony _harmony; internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; ConfigEnabled = ((BaseUnityPlugin)this).Config.Bind("聊天", "启用聊天", true, "启用多人文字聊天功能"); ConfigChatKey = ((BaseUnityPlugin)this).Config.Bind("聊天", "聊天快捷键", (KeyCode)47, "打开聊天输入框的按键"); ConfigChatX = ((BaseUnityPlugin)this).Config.Bind("聊天", "X坐标", 20f, "聊天窗口左下角X坐标"); ConfigChatY = ((BaseUnityPlugin)this).Config.Bind("聊天", "Y坐标", 20f, "聊天窗口左下角Y坐标"); ConfigChatW = ((BaseUnityPlugin)this).Config.Bind("聊天", "宽度", 420f, "聊天窗口宽度"); ConfigChatH = ((BaseUnityPlugin)this).Config.Bind("聊天", "高度", 300f, "聊天窗口高度"); ConfigChatFontSize = ((BaseUnityPlugin)this).Config.Bind("聊天", "字体大小", 18f, "聊天文字大小"); ConfigChatBgAlpha = ((BaseUnityPlugin)this).Config.Bind("聊天", "背景透明度", 0.3f, "聊天背景不透明度(0-1)"); ConfigChatBoxHideDelay = ((BaseUnityPlugin)this).Config.Bind("聊天", "聊天框消失延迟", 0f, "无操作多少秒后聊天框自动隐藏(0=永不消失)"); ConfigContinuousMode = ((BaseUnityPlugin)this).Config.Bind("聊天", "连续输入模式", false, "回车发言后不关闭输入框,空输入时回车关闭"); _harmony = new Harmony("com.github.peaktextchatcn"); _harmony.PatchAll(typeof(GUIManagerPatch)); ((BaseUnityPlugin)this).Config.SettingChanged += OnSettingChanged; Log.LogInfo((object)"PeakTextChatCN v1.0.1 loaded."); } private void OnSettingChanged(object sender, SettingChangedEventArgs e) { //IL_003b: 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: Expected O, but got Unknown if ((object)e.ChangedSetting == ConfigEnabled) { if (ConfigEnabled.Value) { if ((Object)(object)TextChatController.Instance == (Object)null && (Object)(object)GUIManager.instance != (Object)null) { GameObject val = new GameObject("TextChatController"); Object.DontDestroyOnLoad((Object)val); val.AddComponent(); } } else if ((Object)(object)TextChatController.Instance != (Object)null) { Object.Destroy((Object)(object)((Component)TextChatController.Instance).gameObject); } Log.LogInfo((object)("[Config] 聊天 " + (ConfigEnabled.Value ? "已启用" : "已关闭"))); } else if ((object)e.ChangedSetting == ConfigChatX || (object)e.ChangedSetting == ConfigChatY || (object)e.ChangedSetting == ConfigChatW || (object)e.ChangedSetting == ConfigChatH || (object)e.ChangedSetting == ConfigChatFontSize || (object)e.ChangedSetting == ConfigChatBgAlpha || (object)e.ChangedSetting == ConfigChatBoxHideDelay || (object)e.ChangedSetting == ConfigChatKey || (object)e.ChangedSetting == ConfigContinuousMode) { TextChatController.Instance?.ApplyConfig(); } } private void OnDestroy() { ((BaseUnityPlugin)this).Config.SettingChanged -= OnSettingChanged; Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } [HarmonyPatch(typeof(GUIManager), "Start")] public static class GUIManagerPatch { [HarmonyPostfix] public static void Postfix() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown if (Plugin.ConfigEnabled.Value && (Object)(object)TextChatController.Instance == (Object)null) { GameObject val = new GameObject("TextChatController"); Object.DontDestroyOnLoad((Object)val); val.AddComponent(); } } } public class TextChatController : MonoBehaviour { [HarmonyPatch(typeof(GUIManager), "UpdateWindowStatus")] private static class InputBlockPatch { [HarmonyPostfix] public static void Postfix() { TextChatController instance = Instance; if (!((Object)(object)instance == (Object)null) && instance.IsInputBlocked()) { GUIManager instance2 = GUIManager.instance; if ((Object)(object)instance2 != (Object)null) { instance2.windowBlockingInput = true; } } } } [HarmonyPatch(typeof(GUIManager), "UpdatePaused")] private static class PauseBlockPatch { [HarmonyPrefix] public static bool Prefix(GUIManager __instance) { TextChatController instance = Instance; if ((Object)(object)instance != (Object)null && instance.IsInputBlocked() && (Object)(object)__instance.pauseMenu != (Object)null && !__instance.pauseMenu.activeSelf) { return false; } return true; } } [HarmonyPatch(typeof(CinemaCamera), "Update")] private static class CinemaCamPatch { [HarmonyPrefix] public static bool Prefix() { TextChatController instance = Instance; if (!((Object)(object)instance == (Object)null)) { return !instance.IsInputBlocked(); } return true; } } [HarmonyPatch(typeof(Character), "UpdateVariablesFixed")] private static class InteractBlockPatch { [HarmonyPrefix] public static void Prefix(Character __instance) { TextChatController instance = Instance; if ((Object)(object)instance != (Object)null && instance.IsInputBlocked() && (Object)(object)__instance.input != (Object)null) { __instance.input.interactIsPressed = false; } } } private const byte EVT_CODE = 81; private const byte PROTOCOL_V = 1; private const byte TYPE_CHAT = 0; private const int MAX_MSG = 50; private const float INPUT_HEIGHT = 36f; private const float PLACEHOLDER_ALPHA = 0.4f; private const string PLACEHOLDER_MSG = "按 / 聊天..."; private Canvas _canvas; private GameObject _root; private RectTransform _rootRt; private TMP_InputField _input; private ScrollRect _scroll; private Transform _msgParent; private TMP_FontAsset _font; private TextMeshProUGUI _placeholderText; private bool _typing; private int _framesSinceBlock = 100; private float _typingStartTime; private readonly List _msgs = new List(); private readonly Dictionary _names = new Dictionary(); private readonly Dictionary _alive = new Dictionary(); private readonly Dictionary _knocked = new Dictionary(); private bool _firstFrame = true; private bool _rebuilding; private float _reinitTimer; private float _lastActivityTime; private float _chatBoxAlpha = 1f; private Harmony _harmony; private bool _loggedRunning; internal static TextChatController Instance { get; private set; } private void Awake() { Instance = this; ((MonoBehaviour)this).StartCoroutine(Init()); } private IEnumerator Init() { yield return (object)new WaitForSeconds(2f); if ((Object)(object)GUIManager.instance == (Object)null) { yield return (object)new WaitForSeconds(3f); if ((Object)(object)GUIManager.instance == (Object)null) { Plugin.Log.LogError((object)"[Chat] GUIManager null"); Object.Destroy((Object)(object)((Component)this).gameObject); yield break; } } try { if ((Object)(object)_canvas == (Object)null) { BuildUI(); EnsureInputModule(); } PhotonNetwork.NetworkingClient.EventReceived += OnEvent; SceneManager.sceneLoaded += OnSceneLoaded; _harmony = new Harmony("com.github.peaktextchatcn.input"); _harmony.PatchAll(typeof(InputBlockPatch)); _harmony.PatchAll(typeof(PauseBlockPatch)); _harmony.PatchAll(typeof(CinemaCamPatch)); _harmony.PatchAll(typeof(InteractBlockPatch)); Plugin.Log.LogInfo((object)"[Chat] Initialized."); } catch (Exception arg) { Plugin.Log.LogError((object)$"[Chat] Init: {arg}"); } } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { Plugin.Log.LogInfo((object)("[Chat] Scene loaded: " + ((Scene)(ref scene)).name + ", rebuilding UI...")); ((MonoBehaviour)this).StartCoroutine(RebuildUI()); } private IEnumerator RebuildUI() { _rebuilding = true; yield return (object)new WaitForSeconds(2f); if ((Object)(object)GUIManager.instance?.hudCanvas == (Object)null) { yield return (object)new WaitForSeconds(3f); if ((Object)(object)GUIManager.instance?.hudCanvas == (Object)null) { Plugin.Log.LogWarning((object)"[Chat] GUIManager still null after scene load"); _rebuilding = false; yield break; } } CleanupUI(); _names.Clear(); _alive.Clear(); _knocked.Clear(); _firstFrame = true; _typing = false; _framesSinceBlock = 100; BuildUI(); EnsureInputModule(); _rebuilding = false; Plugin.Log.LogInfo((object)"[Chat] UI rebuilt after scene transition."); } private void EnsureInputModule() { EventSystem current = EventSystem.current; if ((Object)(object)current == (Object)null) { Plugin.Log.LogWarning((object)"[Chat] No EventSystem found!"); return; } BaseInputModule[] components = ((Component)current).GetComponents(); bool flag = false; BaseInputModule[] array = components; foreach (BaseInputModule val in array) { Plugin.Log.LogInfo((object)("[Chat] EventSystem module: " + ((object)val).GetType().Name)); if (val is StandaloneInputModule) { flag = true; } } if (!flag) { Plugin.Log.LogInfo((object)"[Chat] Adding StandaloneInputModule for TMP_InputField compatibility"); ((Component)current).gameObject.AddComponent(); } } private void BuildUI() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown //IL_0118: 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_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Expected O, but got Unknown //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Expected O, but got Unknown //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: 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) //IL_0319: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Expected O, but got Unknown GUIManager instance = GUIManager.instance; TextMeshProUGUI heroDayText = instance.heroDayText; _font = ((heroDayText != null) ? ((TMP_Text)heroDayText).font : null); _canvas = new GameObject("ChatCanvas").AddComponent(); ((Component)_canvas).transform.SetParent(((Component)instance).transform, false); _canvas.renderMode = (RenderMode)0; _canvas.sortingOrder = 10; CanvasScaler obj = ((Component)_canvas).gameObject.AddComponent(); obj.uiScaleMode = (ScaleMode)1; obj.referenceResolution = new Vector2(1920f, 1080f); obj.matchWidthOrHeight = 1f; ((Component)_canvas).gameObject.AddComponent(); Plugin.Log.LogInfo((object)("[Chat] Canvas parent=" + ((Object)((Component)instance).gameObject).name + ", renderMode=ScreenSpaceOverlay")); _root = new GameObject("ChatRoot"); _rootRt = _root.AddComponent(); ((Transform)_rootRt).SetParent(((Component)_canvas).transform, false); RectTransform rootRt = _rootRt; RectTransform rootRt2 = _rootRt; Vector2 val = (_rootRt.pivot = Vector2.zero); Vector2 anchorMin = (rootRt2.anchorMax = val); rootRt.anchorMin = anchorMin; _rootRt.anchoredPosition = new Vector2(Plugin.ConfigChatX.Value, Plugin.ConfigChatY.Value); _rootRt.sizeDelta = new Vector2(Plugin.ConfigChatW.Value, Plugin.ConfigChatH.Value); CanvasGroup obj2 = _root.AddComponent(); obj2.blocksRaycasts = true; obj2.interactable = true; ProceduralImage obj3 = _root.AddComponent(); obj3.ModifierType = typeof(UniformModifier); UniformModifier component = ((Component)obj3).GetComponent(); if ((Object)(object)component != (Object)null) { component.Radius = 12f; } ((Graphic)obj3).color = new Color(0f, 0f, 0f, Plugin.ConfigChatBgAlpha.Value); GameObject val3 = new GameObject("ScrollView"); RectTransform val4 = val3.AddComponent(); ((Transform)val4).SetParent(_root.transform, false); val4.anchorMin = Vector2.zero; val4.anchorMax = Vector2.one; val4.pivot = new Vector2(0.5f, 1f); val4.offsetMin = new Vector2(4f, 40f); val4.offsetMax = new Vector2(-4f, -4f); val3.AddComponent(); GameObject val5 = new GameObject("Content"); RectTransform val6 = val5.AddComponent(); ((Transform)val6).SetParent(val3.transform, false); val6.anchorMin = new Vector2(0f, 0f); val6.anchorMax = new Vector2(1f, 0f); val6.pivot = new Vector2(0.5f, 0f); val6.sizeDelta = Vector2.zero; VerticalLayoutGroup obj4 = val5.AddComponent(); ((HorizontalOrVerticalLayoutGroup)obj4).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj4).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)obj4).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj4).childForceExpandWidth = true; ((LayoutGroup)obj4).childAlignment = (TextAnchor)7; ((HorizontalOrVerticalLayoutGroup)obj4).spacing = 2f; ((LayoutGroup)obj4).padding = new RectOffset(4, 4, 2, 2); val5.AddComponent().verticalFit = (FitMode)2; _scroll = val3.AddComponent(); _scroll.content = val6; _scroll.viewport = val4; _scroll.horizontal = false; _scroll.vertical = true; _scroll.movementType = (MovementType)2; _scroll.verticalNormalizedPosition = 0f; _msgParent = val5.transform; BuildInput(_root.transform); _lastActivityTime = Time.time; _chatBoxAlpha = 1f; } private void BuildInput(Transform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Expected O, but got Unknown //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0221: 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_0237: 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_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Unknown result type (might be due to invalid IL or missing references) //IL_0349: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_0359: Unknown result type (might be due to invalid IL or missing references) //IL_0365: Unknown result type (might be due to invalid IL or missing references) //IL_0371: Unknown result type (might be due to invalid IL or missing references) //IL_037d: Unknown result type (might be due to invalid IL or missing references) //IL_03a5: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("InputField"); RectTransform obj = val.AddComponent(); ((Transform)obj).SetParent(parent, false); obj.anchorMin = new Vector2(0f, 0f); obj.anchorMax = new Vector2(1f, 0f); obj.pivot = new Vector2(0.5f, 0f); obj.anchoredPosition = new Vector2(0f, 4f); obj.sizeDelta = new Vector2(-8f, 36f); ProceduralImage val2 = val.AddComponent(); val2.ModifierType = typeof(UniformModifier); UniformModifier component = ((Component)val2).GetComponent(); if ((Object)(object)component != (Object)null) { component.Radius = 8f; } ((Graphic)val2).color = new Color(0f, 0f, 0f, 0.4f); GameObject val3 = new GameObject("Text Area"); RectTransform val4 = val3.AddComponent(); ((Transform)val4).SetParent(val.transform, false); val4.anchorMin = Vector2.zero; val4.anchorMax = Vector2.one; val4.offsetMin = new Vector2(8f, 4f); val4.offsetMax = new Vector2(-8f, -4f); val3.AddComponent(); GameObject val5 = new GameObject("Placeholder"); RectTransform obj2 = val5.AddComponent(); ((Transform)obj2).SetParent(val3.transform, false); obj2.anchorMin = Vector2.zero; obj2.anchorMax = Vector2.one; Vector2 offsetMin = (obj2.offsetMax = Vector2.zero); obj2.offsetMin = offsetMin; TextMeshProUGUI val6 = val5.AddComponent(); if ((Object)(object)_font != (Object)null) { ((TMP_Text)val6).font = _font; } ((TMP_Text)val6).fontSize = Plugin.ConfigChatFontSize.Value - 2f; ((Graphic)val6).color = new Color(1f, 1f, 1f, 0.4f); ((TMP_Text)val6).text = "按 / 聊天..."; ((TMP_Text)val6).enableWordWrapping = false; ((TMP_Text)val6).extraPadding = true; _placeholderText = val6; GameObject val7 = new GameObject("Text"); RectTransform obj3 = val7.AddComponent(); ((Transform)obj3).SetParent(val3.transform, false); obj3.anchorMin = Vector2.zero; obj3.anchorMax = Vector2.one; offsetMin = (obj3.offsetMax = Vector2.zero); obj3.offsetMin = offsetMin; TextMeshProUGUI val8 = val7.AddComponent(); if ((Object)(object)_font != (Object)null) { ((TMP_Text)val8).font = _font; } ((TMP_Text)val8).fontSize = Plugin.ConfigChatFontSize.Value; ((Graphic)val8).color = Color.white; ((TMP_Text)val8).enableWordWrapping = false; ((TMP_Text)val8).extraPadding = true; _input = val.AddComponent(); _input.textViewport = val4; _input.textComponent = (TMP_Text)(object)val8; _input.placeholder = (Graphic)(object)val6; ((Selectable)_input).image = (Image)(object)val2; _input.pointSize = Plugin.ConfigChatFontSize.Value; _input.lineType = (LineType)0; ((UnityEvent)(object)_input.onEndEdit).AddListener((UnityAction)OnSubmit); ((UnityEvent)(object)_input.onValueChanged).AddListener((UnityAction)OnTextChanged); _input.onFocusSelectAll = false; ColorBlock colors = ((Selectable)_input).colors; ((ColorBlock)(ref colors)).normalColor = Color.white; ((ColorBlock)(ref colors)).highlightedColor = Color.white; ((ColorBlock)(ref colors)).pressedColor = Color.white; ((ColorBlock)(ref colors)).selectedColor = Color.white; ((ColorBlock)(ref colors)).disabledColor = Color.gray; ((ColorBlock)(ref colors)).fadeDuration = 0f; ((ColorBlock)(ref colors)).colorMultiplier = 1f; ((Selectable)_input).colors = colors; } private void AddMsg(string text, Color color) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Msg"); ((Transform)val.AddComponent()).SetParent(_msgParent, false); val.AddComponent().flexibleWidth = 1f; TextMeshProUGUI val2 = val.AddComponent(); if ((Object)(object)_font != (Object)null) { ((TMP_Text)val2).font = _font; } ((TMP_Text)val2).fontSize = Plugin.ConfigChatFontSize.Value; ((Graphic)val2).color = color; ((TMP_Text)val2).enableWordWrapping = true; ((TMP_Text)val2).richText = true; ((Graphic)val2).raycastTarget = false; ((TMP_Text)val2).text = text; _msgs.Add(val); while (_msgs.Count > 50) { if ((Object)(object)_msgs[0] != (Object)null) { Object.Destroy((Object)(object)_msgs[0]); } _msgs.RemoveAt(0); } _scroll.verticalNormalizedPosition = 0f; Canvas.ForceUpdateCanvases(); Transform msgParent = _msgParent; LayoutRebuilder.ForceRebuildLayoutImmediate((RectTransform)(object)((msgParent is RectTransform) ? msgParent : null)); _scroll.verticalNormalizedPosition = 0f; _lastActivityTime = Time.time; _chatBoxAlpha = 1f; SetChatBoxAlpha(1f); } private void AddSysMsg(string text) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) AddMsg("[系统] " + text, new Color(0.6f, 0.6f, 0.6f)); } private void OnTextChanged(string text) { UpdateImeCursorPos(); } private void SetPlaceholderText(bool visible) { if (!((Object)(object)_placeholderText == (Object)null)) { ((TMP_Text)_placeholderText).text = (visible ? "按 / 聊天..." : ""); } } private void UpdateImeCursorPos() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_input == (Object)null) { return; } try { RectTransform component = ((Component)_input).GetComponent(); if (!((Object)(object)component == (Object)null)) { Vector2 val = RectTransformUtility.WorldToScreenPoint((Camera)null, ((Transform)component).position); float num = 0f; if ((Object)(object)_input.textComponent != (Object)null && !string.IsNullOrEmpty(_input.text)) { num = _input.textComponent.preferredWidth; } Input.compositionCursorPos = new Vector2(val.x + num, (float)Screen.height - val.y); } } catch { } } private void OnSubmit(string text) { //IL_004e: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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_00aa: Unknown result type (might be due to invalid IL or missing references) if (!string.IsNullOrWhiteSpace(text)) { SendMsg(text); Character localCharacter = Character.localCharacter; Color? obj; if (localCharacter == null) { obj = null; } else { CharacterRefs refs = localCharacter.refs; if (refs == null) { obj = null; } else { CharacterCustomization customization = refs.customization; obj = ((customization != null) ? new Color?(customization.PlayerColor) : ((Color?)null)); } } Color val = (Color)(((??)obj) ?? Color.white); AddMsg("<#" + ColorUtility.ToHtmlStringRGB(val) + ">" + PhotonNetwork.NickName + ": " + text, Color.white); } if (Plugin.ConfigContinuousMode.Value && !string.IsNullOrWhiteSpace(text)) { if ((Object)(object)_input != (Object)null) { _input.text = ""; } _typing = true; _framesSinceBlock = 0; _typingStartTime = Time.unscaledTime; ((MonoBehaviour)this).StartCoroutine(ReactivateInput()); return; } _typing = false; _framesSinceBlock = 10; if ((Object)(object)_input != (Object)null) { _input.text = ""; } SetPlaceholderText(visible: true); if ((Object)(object)EventSystem.current != (Object)null) { EventSystem.current.SetSelectedGameObject((GameObject)null); } } private IEnumerator ReactivateInput() { yield return null; if ((Object)(object)_input != (Object)null) { _lastActivityTime = Time.time; _input.ActivateInputField(); SetPlaceholderText(visible: false); if ((Object)(object)EventSystem.current != (Object)null) { EventSystem.current.SetSelectedGameObject(((Component)_input).gameObject); } UpdateImeCursorPos(); } } private void SendMsg(string text) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) PhotonNetwork.RaiseEvent((byte)81, (object)new object[4] { (byte)1, (byte)0, PhotonNetwork.NickName, text }, RaiseEventOptions.Default, SendOptions.SendReliable); } private void OnEvent(EventData data) { //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: 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) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) if (data.Code != 81 || !(data.CustomData is object[] array) || array.Length < 4 || !(array[0] is byte b) || b < 1 || !(array[2] is string text) || !(array[3] is string text2)) { return; } Character obj = FindCharByNick(text); Color? obj2; if (obj == null) { obj2 = null; } else { CharacterRefs refs = obj.refs; if (refs == null) { obj2 = null; } else { CharacterCustomization customization = refs.customization; obj2 = ((customization != null) ? new Color?(customization.PlayerColor) : ((Color?)null)); } } Color val = (Color)(((??)obj2) ?? Color.white); AddMsg("<#" + ColorUtility.ToHtmlStringRGB(val) + ">" + text + ": " + text2, Color.white); } private static Character FindCharByNick(string nick) { if (Character.AllCharacters == null) { return null; } foreach (Character allCharacter in Character.AllCharacters) { if ((Object)(object)allCharacter != (Object)null && allCharacter.characterName == nick) { return allCharacter; } } return null; } public void ApplyConfig() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_rootRt != (Object)null)) { return; } _rootRt.anchoredPosition = new Vector2(Plugin.ConfigChatX.Value, Plugin.ConfigChatY.Value); _rootRt.sizeDelta = new Vector2(Plugin.ConfigChatW.Value, Plugin.ConfigChatH.Value); ProceduralImage component = _root.GetComponent(); if ((Object)(object)component != (Object)null) { ((Graphic)component).color = new Color(0f, 0f, 0f, Plugin.ConfigChatBgAlpha.Value); } float value = Plugin.ConfigChatFontSize.Value; if ((Object)(object)_input != (Object)null) { _input.pointSize = value; if ((Object)(object)_input.textComponent != (Object)null) { _input.textComponent.fontSize = value; } if ((Object)(object)_placeholderText != (Object)null) { ((TMP_Text)_placeholderText).fontSize = value - 2f; } } foreach (GameObject msg in _msgs) { if ((Object)(object)msg != (Object)null) { TextMeshProUGUI component2 = msg.GetComponent(); if ((Object)(object)component2 != (Object)null) { ((TMP_Text)component2).fontSize = value; } } } ProceduralImage[] componentsInChildren = _root.GetComponentsInChildren(true); foreach (ProceduralImage obj in componentsInChildren) { ((Graphic)obj).SetVerticesDirty(); ((Graphic)obj).SetLayoutDirty(); } if ((Object)(object)_canvas != (Object)null) { Canvas.ForceUpdateCanvases(); } } internal bool IsInputBlocked() { if (!_typing) { return _framesSinceBlock <= 1; } return true; } private void ActivateInput() { _typing = true; _framesSinceBlock = 0; _typingStartTime = Time.unscaledTime; _lastActivityTime = Time.time; _chatBoxAlpha = 1f; SetChatBoxAlpha(1f); if ((Object)(object)_input != (Object)null) { _input.text = ""; _input.ActivateInputField(); SetPlaceholderText(visible: false); if ((Object)(object)EventSystem.current != (Object)null) { EventSystem.current.SetSelectedGameObject(((Component)_input).gameObject); } UpdateImeCursorPos(); } } private void HandleInput() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) if (Input.GetKeyDown(Plugin.ConfigChatKey.Value) && !_typing) { ActivateInput(); } else { if (!_typing) { return; } if (Input.GetKeyDown((KeyCode)27)) { DeactivateInput(); return; } float y = Input.mouseScrollDelta.y; if (y != 0f && (Object)(object)_scroll != (Object)null) { _scroll.verticalNormalizedPosition = Mathf.Clamp01(_scroll.verticalNormalizedPosition + y * 0.16f); } } } private void DeactivateInput() { _typing = false; _framesSinceBlock = 10; if ((Object)(object)_input != (Object)null) { _input.text = ""; _input.DeactivateInputField(false); SetPlaceholderText(visible: true); } if ((Object)(object)_scroll != (Object)null) { _scroll.verticalNormalizedPosition = 0f; } if ((Object)(object)EventSystem.current != (Object)null) { EventSystem.current.SetSelectedGameObject((GameObject)null); } } private void LateUpdate() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (!_loggedRunning) { _loggedRunning = true; Plugin.Log.LogInfo((object)string.Format("[Chat] Running, key={0}, input={1}, root={2}, canvas={3}", Plugin.ConfigChatKey.Value, ((Object)(object)_input != (Object)null) ? "OK" : "NULL", ((Object)(object)_root != (Object)null) ? "OK" : "NULL", ((Object)(object)_canvas != (Object)null) ? "OK" : "NULL")); } if (IsInputBlocked()) { _framesSinceBlock = 0; } else if (_framesSinceBlock < 100) { _framesSinceBlock++; } if (_typing) { UpdateImeCursorPos(); if ((Object)(object)_input == (Object)null || (!_input.isFocused && Time.unscaledTime - _typingStartTime > 5f)) { DeactivateInput(); } } if ((Object)(object)_canvas == (Object)null && !_rebuilding && (Object)(object)GUIManager.instance?.hudCanvas != (Object)null) { _reinitTimer += Time.deltaTime; if (_reinitTimer >= 2f) { _reinitTimer = 0f; Plugin.Log.LogInfo((object)"[Chat] Canvas lost, rebuilding (fallback)..."); CleanupUI(); _names.Clear(); _alive.Clear(); _knocked.Clear(); _firstFrame = true; _typing = false; _framesSinceBlock = 100; BuildUI(); } } else { HandleInput(); TrackCharacters(); UpdateChatBoxVisibility(); } } private void TrackCharacters() { if (Character.AllCharacters == null) { return; } if (_firstFrame) { foreach (Character allCharacter in Character.AllCharacters) { if (!((Object)(object)allCharacter == (Object)null)) { int instanceID = ((Object)allCharacter).GetInstanceID(); _names[instanceID] = allCharacter.characterName; _alive[instanceID] = !allCharacter.data.dead; _knocked[instanceID] = (Object)(object)allCharacter.refs?.afflictions != (Object)null && allCharacter.refs.afflictions.statusSum >= 1f; } } _firstFrame = false; return; } HashSet hashSet = new HashSet(); foreach (Character allCharacter2 in Character.AllCharacters) { if ((Object)(object)allCharacter2 == (Object)null) { continue; } int instanceID2 = ((Object)allCharacter2).GetInstanceID(); hashSet.Add(instanceID2); if (!_names.ContainsKey(instanceID2)) { _names[instanceID2] = allCharacter2.characterName; AddSysMsg(allCharacter2.characterName + " 加入了游戏"); _alive[instanceID2] = !allCharacter2.data.dead; _knocked[instanceID2] = false; continue; } bool flag = !allCharacter2.data.dead; bool flag2 = (Object)(object)allCharacter2.refs?.afflictions != (Object)null && allCharacter2.refs.afflictions.statusSum >= 1f; bool num = _alive[instanceID2]; bool flag3 = _knocked[instanceID2]; if (num && !flag) { AddSysMsg(_names[instanceID2] + " 已死亡"); } else if (flag3 && !flag2 && flag) { AddSysMsg(_names[instanceID2] + " 已苏醒"); } else if (!flag3 && flag2 && flag) { AddSysMsg(_names[instanceID2] + " 昏迷了"); } _alive[instanceID2] = flag; _knocked[instanceID2] = flag2; } List list = new List(); foreach (KeyValuePair name in _names) { if (!hashSet.Contains(name.Key)) { list.Add(name.Key); } } foreach (int item in list) { AddSysMsg(_names[item] + " 离开了游戏"); _names.Remove(item); _alive.Remove(item); _knocked.Remove(item); } } private void UpdateChatBoxVisibility() { float value = Plugin.ConfigChatBoxHideDelay.Value; if (value <= 0f) { if (_chatBoxAlpha < 1f) { _chatBoxAlpha = 1f; SetChatBoxAlpha(1f); } return; } if (_typing) { _lastActivityTime = Time.time; if (_chatBoxAlpha < 1f) { _chatBoxAlpha = 1f; SetChatBoxAlpha(1f); } return; } float num = Time.time - _lastActivityTime; float num2 = ((num < value) ? 1f : ((!(num < value + 1f)) ? 0f : (1f - (num - value)))); if (Mathf.Abs(_chatBoxAlpha - num2) > 0.01f) { _chatBoxAlpha = num2; SetChatBoxAlpha(num2); } } private void SetChatBoxAlpha(float alpha) { if ((Object)(object)_root != (Object)null) { CanvasGroup component = _root.GetComponent(); if ((Object)(object)component != (Object)null) { component.alpha = alpha; } } } private void CleanupUI() { if ((Object)(object)_canvas != (Object)null) { Object.Destroy((Object)(object)((Component)_canvas).gameObject); } _canvas = null; _root = null; _rootRt = null; _input = null; _scroll = null; _msgParent = null; _placeholderText = null; _msgs.Clear(); } private void OnDestroy() { if (!((Object)(object)Instance != (Object)(object)this)) { try { PhotonNetwork.NetworkingClient.EventReceived -= OnEvent; } catch { } try { SceneManager.sceneLoaded -= OnSceneLoaded; } catch { } CleanupUI(); Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } Instance = null; Plugin.Log.LogInfo((object)"[Chat] Destroyed."); } } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }