| using UnityEngine; | 
| using System.Collections; | 
| using System.Collections.Generic; | 
| using UnityEngine.UI; | 
| using DG.Tweening; | 
| using Cysharp.Threading.Tasks; | 
|   | 
| using System; | 
|   | 
| using System.Text.RegularExpressions; | 
| using DG.Tweening; | 
|   | 
| public class MessageWin : UIBase | 
| { | 
|     [SerializeField] RectTransform m_ContainerNormalHint; | 
|     [SerializeField] RichText m_NormalHint; | 
|     [SerializeField] RectTransform m_ContainerChatHint; | 
|     [SerializeField] RichText m_NormalChatHint; //显示在聊天界面的位置 | 
|   | 
|     [SerializeField] RectTransform m_ContainerServerTip; | 
|     [SerializeField] ScaleTween m_ServerTipScaleTween; | 
|     [SerializeField] PositionTween m_ServerTipPositionTween; | 
|     [SerializeField] RichText m_ServerTip; | 
|     [SerializeField, Header("全服广播停留时间")] float m_ServerTipKeepTime = 1.5f; | 
|   | 
|     [SerializeField] RectTransform m_ContainerGM; | 
|     [SerializeField] Text m_GmRichText; | 
|     [SerializeField] ScrollerController m_ScrollControl; | 
|     [SerializeField] Toggle m_AutoPopToggle; | 
|     [SerializeField] Toggle m_AutoRefreshToggle; | 
|     [SerializeField] Button m_GMClose; | 
|   | 
|     bool m_ServerTipPrepared = true; | 
|   | 
|     // 生命周期 | 
|     protected override void Awake() | 
|     { | 
|         base.Awake(); | 
|     } | 
|   | 
|     protected override void Start() | 
|     { | 
|         base.Start(); | 
|         // 初始化数据 | 
|     } | 
|   | 
|     protected override void InitComponent() | 
|     { | 
|         base.InitComponent(); | 
|         // 初始化组件 | 
|         m_ContainerNormalHint.OnWaitCompelete(OnHintDisplayComplete); | 
|         m_ContainerChatHint.OnWaitCompelete(OnHintDisplayComplete); | 
|         m_ScrollControl.OnRefreshCell += OnRefreshGmCell; | 
|         m_ScrollControl.OnGetDynamicSize += OnGetDynamicSize; | 
|         m_ScrollControl.lockType = EnhanceLockType.LockVerticalBottom; | 
|         m_GMClose.onClick.AddListener(OnGMClose); | 
|     } | 
|   | 
|     protected override void OnPreOpen() | 
|     { | 
|         // 子类可以重写此方法进行额外的预打开操作 | 
|         base.OnPreOpen(); | 
|         m_ServerTipPrepared = true; | 
|   | 
| #if UNITY_EDITOR | 
|         m_ContainerGM.SetActive(VersionConfig.Get().debugVersion); | 
| #else | 
|         m_ContainerGM.SetActive(false); | 
| #endif | 
|         ServerTipDetails.normalHintRefresh += CheckNormalHint; | 
|         ServerTipDetails.serverHintRefresh += CheckServerHint; | 
|         ServerTipDetails.gmMessageRefresh += DisplayGM; | 
|         ServerTipDetails.gmOpenEvent += GmOpenEvent; | 
|         ServerTipDetails.chatHintRefresh += CheckChatHint; | 
|         CheckNormalHint(); | 
|         CheckChatHint(); | 
|         CheckServerHint(); | 
|         DisplayGM(string.Empty); | 
|   | 
|         if (ServerTipDetails.requireOpenGM) | 
|         { | 
|             if (hasOnFrom) | 
|             { | 
|                 OnGMOpen(); | 
|             } | 
|             ServerTipDetails.requireOpenGM = false; | 
|         } | 
|     } | 
|   | 
|     // UI事件 | 
|     protected override void OnOpen() | 
|     { | 
|         base.OnOpen(); | 
|         // 窗口打开时的逻辑 | 
|     } | 
|   | 
|     protected override void OnClose() | 
|     { | 
|         base.OnClose(); | 
|         ServerTipDetails.normalHintRefresh -= CheckNormalHint; | 
|         ServerTipDetails.serverHintRefresh -= CheckServerHint; | 
|         ServerTipDetails.gmMessageRefresh -= DisplayGM; | 
|         ServerTipDetails.gmOpenEvent -= GmOpenEvent; | 
|         ServerTipDetails.chatHintRefresh -= CheckChatHint; | 
|         // 窗口关闭时的逻辑 | 
|          | 
|     } | 
|   | 
|     private void GmOpenEvent() | 
|     { | 
|         if (ServerTipDetails.requireOpenGM) | 
|         { | 
|             OnGMOpen(); | 
|             ServerTipDetails.requireOpenGM = false; | 
|         } | 
|     } | 
|   | 
|     private void OnDisable() | 
|     { | 
|         m_ContainerNormalHint.SetActive(false); | 
|         m_ContainerChatHint.SetActive(false); | 
|         DisableServerTip(); | 
|         StopAllCoroutines(); | 
|     } | 
|   | 
|     void CheckNormalHint() | 
|     { | 
|         var hint = ServerTipDetails.RequireNormalHint(); | 
|         if (hint != null) | 
|         { | 
|             DisplayNormalHint(hint); | 
|         } | 
|     } | 
|   | 
|     void DisplayNormalHint(SystemHintData hint) | 
|     { | 
|         transform.SetAsLastSibling(); | 
|         m_NormalHint.SetExtenalData(hint.extentionData); | 
|         m_NormalHint.text = hint.message; | 
|         if (!m_ContainerNormalHint.gameObject.activeInHierarchy) | 
|         { | 
|             m_ContainerNormalHint.SetActive(true); | 
|         } | 
|         m_ContainerNormalHint.DoWaitRestart(); | 
|     } | 
|   | 
|     private void OnHintDisplayComplete(Component com) | 
|     { | 
|         com.DoWaitStop(); | 
|         com.SetActive(false); | 
|     } | 
|   | 
|     void CheckServerHint() | 
|     { | 
|         if (!m_ServerTipPrepared) | 
|         { | 
|             return; | 
|         } | 
|         var hint = ServerTipDetails.RequireServerTip(); | 
|         if (hint != null && gameObject.activeInHierarchy) | 
|         { | 
|             DisplayServerHint(hint); | 
|         } | 
|         else | 
|         { | 
|             DisableServerTip(); | 
|         } | 
|     } | 
|   | 
|     public void DisplayServerHint(SystemHintData hint) | 
|     { | 
|         transform.SetAsLastSibling(); | 
|         m_ServerTipPrepared = false; | 
|         if (!m_ServerTipScaleTween.gameObject.activeSelf) | 
|         { | 
|             m_ServerTipScaleTween.SetActive(true); | 
|         } | 
|         m_ServerTipScaleTween.SetStartState(); | 
|         m_ServerTipPositionTween.SetStartState(); | 
|         m_ContainerServerTip.SetActive(true); | 
|         m_ServerTip.SetExtenalData(hint.extentionData); | 
|         m_ServerTip.text = hint.message; | 
|         m_ServerTipScaleTween.Play(); | 
|         TimeMgr.Instance.Register(m_ServerTip, ServerTipStartHide, m_ServerTipKeepTime + m_ServerTipScaleTween.duration); | 
|     } | 
|   | 
|     private void ServerTipStartHide(Component comp) | 
|     { | 
|         m_ServerTipPositionTween.Play(); | 
|         TimeMgr.Instance.Register(m_ServerTipPositionTween, ServerTipTweenComplete, m_ServerTipPositionTween.duration); | 
|     } | 
|   | 
|     private void ServerTipTweenComplete(Component comp) | 
|     { | 
|         m_ServerTipPrepared = true; | 
|         DisableServerTip(); | 
|         CheckServerHint(); | 
|     } | 
|   | 
|     private void DisableServerTip() | 
|     { | 
|         TimeMgr.Instance.UnRegister(m_ServerTip); | 
|         TimeMgr.Instance.UnRegister(m_ServerTipPositionTween); | 
|         m_ContainerServerTip.SetActive(false); | 
|         m_ServerTipScaleTween.Stop(); | 
|         m_ServerTipPositionTween.Stop(); | 
|         m_ServerTipScaleTween.SetStartState(); | 
|         m_ServerTipPositionTween.SetStartState(); | 
|     } | 
|   | 
|   | 
|     readonly Regex autoPopRegex = new Regex("参数错误|执行GM命令错误|^###"); | 
|     void DisplayGM(string latest) | 
|     { | 
|         if (!string.IsNullOrEmpty(latest)) | 
|         { | 
|             if (m_AutoPopToggle.isOn && hasOnFrom) | 
|             { | 
|                 RectTransform rt = m_ContainerGM; | 
|                 Vector3 pos = new Vector3(hasOnFrom ? -rt.sizeDelta.x / 2 : rt.sizeDelta.x / 2, 0, 0); | 
|                 rt.DOLocalMove(pos, 1.0f); | 
|                 hasOnFrom = !hasOnFrom; | 
|                 m_GMClose.SetActive(!hasOnFrom); | 
|             } | 
|         } | 
|         if (m_ScrollControl.GetNumberOfCells(m_ScrollControl.m_Scorller) >= 300) | 
|         { | 
|             m_ScrollControl.m_Scorller.RefreshActiveCellViews(); | 
|             return; | 
|         } | 
|         m_ScrollControl.Refresh(); | 
|         for (int i = 0; i < ServerTipDetails.gmMessages.Count; i++) | 
|         { | 
|             m_ScrollControl.AddCell(ScrollerDataType.Normal, i); | 
|         } | 
|         m_ScrollControl.Restart(); | 
|         if (autoPopRegex.IsMatch(latest)) | 
|         { | 
|             if (hasOnFrom) | 
|             { | 
|                 OnGMOpen(); | 
|             } | 
|         } | 
|     } | 
|   | 
|     private void OnRefreshGmCell(ScrollerDataType type, CellView cell) | 
|     { | 
|         if (cell.index < ServerTipDetails.gmMessages.Count) | 
|         { | 
|             Text text = cell.transform.Find("Text").GetComponent<Text>(); | 
|             text.text = ServerTipDetails.gmMessages[cell.index]; | 
|         } | 
|     } | 
|   | 
|     private bool OnGetDynamicSize(ScrollerDataType type, int index, out float height) | 
|     { | 
|         var msg = index < ServerTipDetails.gmMessages.Count ? ServerTipDetails.gmMessages[index] : string.Empty; | 
|         height = m_GmRichText.cachedTextGeneratorForLayout.GetPreferredHeight(msg, | 
|             m_GmRichText.GetGenerationSettings(new Vector2(m_GmRichText.rectTransform.rect.size.x, 0.0f))) | 
|             / m_GmRichText.pixelsPerUnit; | 
|         height += 5; | 
|         return true; | 
|     } | 
|   | 
|     private void OnGMClose() | 
|     { | 
|         if (!hasOnFrom) | 
|         { | 
|             RectTransform rt = m_ContainerGM; | 
|             Vector3 pos = new Vector3(hasOnFrom ? -rt.sizeDelta.x / 2 : rt.sizeDelta.x / 2, 0, 0); | 
|             rt.DOLocalMove(pos, 1.0f); | 
|             hasOnFrom = !hasOnFrom; | 
|             m_GMClose.SetActive(!hasOnFrom); | 
|         } | 
|     } | 
|   | 
|     private Vector3 gmTo = new Vector3(442, 0, 0); | 
|     private Vector3 gmFrom = new Vector3(892, 0, 0); | 
|     private bool hasOnFrom = true; | 
|     public void OnGMOpen() | 
|     { | 
|         RectTransform rt = m_ContainerGM; | 
|         Vector3 pos = new Vector3(hasOnFrom ? -rt.sizeDelta.x / 2 : rt.sizeDelta.x / 2, 0, 0); | 
|         rt.DOLocalMove(pos, 1.0f); | 
|         hasOnFrom = !hasOnFrom; | 
|         m_GMClose.SetActive(!hasOnFrom); | 
|     } | 
|   | 
|     void CheckChatHint() | 
|     { | 
|         var hint = ServerTipDetails.RequireChatHint(); | 
|         if (hint != null) | 
|         { | 
|             DisplayChatHint(hint); | 
|         } | 
|     } | 
|   | 
|     void DisplayChatHint(SystemHintData hint) | 
|     { | 
|         if (!UIManager.Instance.IsOpened<ChatWin>()) | 
|         { | 
|             return; | 
|         } | 
|         if (!m_ContainerChatHint.gameObject.activeInHierarchy) | 
|         { | 
|             m_ContainerChatHint.gameObject.SetActive(true); | 
|         } | 
|         m_NormalChatHint.SetExtenalData(hint.extentionData); | 
|         m_NormalChatHint.text = hint.message; | 
|         m_ContainerChatHint.DoWaitRestart(); | 
|     } | 
| } |