From 2636bf475c8b4b03ee869a5db2f5fdd891ed9f97 Mon Sep 17 00:00:00 2001
From: yyl <yyl>
Date: 星期四, 04 十二月 2025 09:19:35 +0800
Subject: [PATCH] Merge branch 'master' of http://192.168.1.20:10010/r/Project_SG_scripts

---
 Main/Core/NetworkPackage/ClientPack/CB3_PlayerSocial/CB320_tagCSTalk.cs                         |   22 
 Main/System/Chat/ChatPlayerMineCell.cs                                                          |   97 
 Main/System/Guild/GuildEmblemModel.cs                                                           |   49 
 Main/ResModule/ResManager.cs                                                                    |    7 
 Main/System/Guild/GuildBossWin.cs                                                               |    4 
 Main/System/Chat/ChatDateCell.cs.meta                                                           |    2 
 Main/Core/NetworkPackage/DTCFile/ServerPack/HB3_PlayerSocial/DTCB311_tagMCTalkCacheList.cs.meta |    2 
 Main/System/Settlement/BattleSettlementManager.cs                                               |    2 
 Main/Core/NetworkPackage/ServerPack/HB3_PlayerSocial/HB310_tagMCTalk.cs                         |   43 
 Main/System/PhantasmPavilion/PhantasmPavilionManager.cs                                         |   27 
 Main/Core/NetworkPackage/DTCFile/ServerPack/HB3_PlayerSocial/DTCB310_tagMCTalk.cs               |   12 
 Main/System/PhantasmPavilion/ChatBubbleHelper.cs                                                |   14 
 Main/System/Message/SysNotifyMgr.cs                                                             |   25 
 Main/Config/Configs/ChatBubbleBoxConfig.cs                                                      |   65 
 Main/Component/UI/Effect/BattleEffectPlayer.cs                                                  |    2 
 Main/System/AssetVersion/InGameDownTestUtility.cs                                               |    6 
 Main/Core/NetworkPackage/ClientPack/CB3_PlayerSocial/CB320_tagCSTalk.cs.meta                    |    2 
 Main/System/Guild/GuildOPWin.cs                                                                 |    1 
 Main/Core/NetworkPackage/ServerPack/HB3_PlayerSocial/HB311_tagMCTalkCacheList.cs.meta           |    2 
 Main/System/Chat/ChatTabCell.cs                                                                 |   46 
 Main/Core/NetworkPackage/ServerPack/HB3_PlayerSocial/HB310_tagMCTalk.cs.meta                    |    2 
 Main/Core/NetworkPackage/DTCFile/ServerPack/HB3_PlayerSocial/DTCB310_tagMCTalk.cs.meta          |    2 
 Main/System/Chat/ChatBubbleBehaviour.cs                                                         |  426 ++--
 Main/Core/NetworkPackage/ClientPack/CB3_PlayerSocial.meta                                       |    8 
 Main/System/Chat/ChatBulletItem.cs                                                              |  128 +
 Main/Core/NetworkPackage/DTCFile/ServerPack/HB3_PlayerSocial.meta                               |    8 
 Main/Core/NetworkPackage/ServerPack/HB3_PlayerSocial/HB311_tagMCTalkCacheList.cs                |   55 
 Main/System/Chat/ChatManager.cs                                                                 | 1965 +++++++-----------------
 Main/System/Chat/ChatSysCell.cs.meta                                                            |    0 
 Main/Core/NetworkPackage/DTCFile/ServerPack/HB3_PlayerSocial/DTCB311_tagMCTalkCacheList.cs      |   12 
 Main/System/Chat/ChatSettingButton.cs                                                           |   27 
 Main/Config/ConfigManager.cs                                                                    |    3 
 Main/System/Login/LoginWin.cs                                                                   |    6 
 Main/System/Chat/ChatSettingButton.cs.meta                                                      |    2 
 Main/System/Chat/ChatWin.cs                                                                     |  735 ++++++---
 Main/System/Main/HomeWin.cs                                                                     |  126 +
 Main/Main.cs                                                                                    |    1 
 Main/Component/UI/EnhancedScroller/EnhancedScroller.cs                                          |  130 +
 Main/System/Chat/ChatBulletView.cs                                                              |  130 +
 Main/Component/UI/Effect/EffectPlayer.cs                                                        |    2 
 Main/System/Chat/ChatTabCell.cs.meta                                                            |    2 
 Main/Core/ResModule/GameObjectPoolManager.cs                                                    |    6 
 Main/System/Guild/GuildManager.cs                                                               |   49 
 Main/System/Guild/GuildBossManager.cs                                                           |   31 
 Main/System/Horse/HorseController.cs                                                            |    2 
 Main/System/Tip/ScrollTip.cs                                                                    |    2 
 Main/System/Chat/ChatDateCell.cs                                                                |   21 
 Main/System/Hero/UIHeroController.cs                                                            |    2 
 Main/Utility/LanguageVerify.cs                                                                  |   84 -
 Main/System/Battle/BattleHUDWin.cs                                                              |    2 
 Main/System/Guild/GuildChangeNameWin.cs                                                         |    5 
 Main/System/Chat/ChatSysCell.cs                                                                 |   32 
 Main/System/Chat/ChatBulletView.cs.meta                                                         |    2 
 Main/System/Chat/ChatPlayerOtherCell.cs                                                         |  105 
 /dev/null                                                                                       |   11 
 Main/Core/NetworkPackage/DataToCtl/PackageRegedit.cs                                            |    4 
 Main/System/Chat/ChatBulletItem.cs.meta                                                         |    2 
 Main/System/Guild/GuildBaseWin.cs                                                               |   87 +
 58 files changed, 2,426 insertions(+), 2,221 deletions(-)

diff --git a/Main/Component/UI/Effect/BattleEffectPlayer.cs b/Main/Component/UI/Effect/BattleEffectPlayer.cs
index 139fc2a..6faac2c 100644
--- a/Main/Component/UI/Effect/BattleEffectPlayer.cs
+++ b/Main/Component/UI/Effect/BattleEffectPlayer.cs
@@ -432,7 +432,7 @@
         }
 
         // 浠庣壒鏁堥鍒朵綋姹犺幏鍙栫壒鏁�
-        pool = GameObjectPoolManager.Instance.RequestPool(effectPrefab);
+        pool = GameObjectPoolManager.Instance.GetPool(effectPrefab);
         effectTarget = pool.Request();
         // 璁剧疆鐖惰妭鐐瑰拰浣嶇疆
         effectTarget.transform.SetParent(transform);
diff --git a/Main/Component/UI/Effect/EffectPlayer.cs b/Main/Component/UI/Effect/EffectPlayer.cs
index 4848b9b..604e5bc 100644
--- a/Main/Component/UI/Effect/EffectPlayer.cs
+++ b/Main/Component/UI/Effect/EffectPlayer.cs
@@ -348,7 +348,7 @@
         }
 
         // 浠庣壒鏁堥鍒朵綋姹犺幏鍙栫壒鏁�
-        pool = GameObjectPoolManager.Instance.RequestPool(effectPrefab);
+        pool = GameObjectPoolManager.Instance.GetPool(effectPrefab);
         effectTarget = pool.Request();
         // 璁剧疆鐖惰妭鐐瑰拰浣嶇疆
         effectTarget.transform.SetParent(transform);
diff --git a/Main/Component/UI/EnhancedScroller/EnhancedScroller.cs b/Main/Component/UI/EnhancedScroller/EnhancedScroller.cs
index ac9609a..0cf4595 100644
--- a/Main/Component/UI/EnhancedScroller/EnhancedScroller.cs
+++ b/Main/Component/UI/EnhancedScroller/EnhancedScroller.cs
@@ -262,7 +262,7 @@
                         // set the vertical position
                         scrollRect.verticalNormalizedPosition = 1f - (_scrollPosition / _ScrollSize);
                         //杩欓噷瑕佹敞鎰忥紝濡傛灉闆嗗悎杩涜杩囧鍒讹紝閭d箞杩欓噷鐨刜scrollSize涔熶竴鏍蜂細姣斿師鏉ョ殑澧炲姞锛屽洜涓篲ScrollSize姘歌繙姣攃ontent鐨勬�诲ぇ灏忓皬涓�涓彲瑙嗗尯澶у皬
-                        
+
                     }
                     else
                     {
@@ -379,9 +379,9 @@
         /// The scroller should only be moving one one axix.
         /// </summary>
         public float LinearVelocity //瀹炶川涓婃槸鎿嶄綔ScrollRect.velocity
-                       //Get : 灏嗗悜閲忚浆涓篺loat绫诲瀷
-                       //Set锛氱敤涓�涓猣loat绫诲瀷鏋勯�犱竴涓浉搴旂殑鍚戦噺
-        //澶栭儴鏂规硶鍙互閫氳繃璁块棶杩欎釜灞炴�ф潵浣縮croll杩愬姩璧锋潵
+                                    //Get : 灏嗗悜閲忚浆涓篺loat绫诲瀷
+                                    //Set锛氱敤涓�涓猣loat绫诲瀷鏋勯�犱竴涓浉搴旂殑鍚戦噺
+                                    //澶栭儴鏂规硶鍙互閫氳繃璁块棶杩欎釜灞炴�ф潵浣縮croll杩愬姩璧锋潵
         {
             get
             {
@@ -450,7 +450,7 @@
                 return _activeCellViewsStartIndex % NumberOfCells;
             }
         }
-        
+
         /// <summary>
         /// This is the last data index showing in the scroller's visible area
         /// </summary>
@@ -462,8 +462,10 @@
             }
         }
 
-        public int ActiveCellCnt {
-            get {
+        public int ActiveCellCnt
+        {
+            get
+            {
                 return _activeCellViews.Count;
             }
         }
@@ -512,7 +514,7 @@
                 var go = Instantiate(cellPrefab.gameObject);
                 cellView = go.GetComponent<EnhancedScrollerCellView>();
                 cellView.transform.SetParent(_container);
-                
+
             }
             Vector3 pos = cellView.transform.localPosition;
             if (pos.x == float.NaN || pos.y == float.NaN)
@@ -881,9 +883,12 @@
         /// Cached reference to the scrollRect
         /// </summary>
         private ScrollRect m_ScrollRect;
-        public ScrollRect scrollRect {
-            get {
-                if (m_ScrollRect == null) {
+        public ScrollRect scrollRect
+        {
+            get
+            {
+                if (m_ScrollRect == null)
+                {
                     m_ScrollRect = this.GetComponent<ScrollRect>();
                 }
                 return m_ScrollRect;
@@ -1075,10 +1080,10 @@
         /// of the scroller
         /// </summary>
         public float _ScrollSize//杩欓噷骞朵笉鏄寚scrllrect鐨勫ぇ灏忥紝鑰屾槸鎸囩湡姝e湪婊戝姩鐨勫尯鍩熺殑澶у皬
-                                /*scrollrect鐨刵ormallizePosition瀹為檯涓婂氨鏄繖涓湡姝h兘婊戝姩鐨勫尯鍩熺殑澶у皬
-                                 * 鍦ㄦ粦鍔ㄨ繃绋嬩腑褰掍竴鍖栫殑鍊硷紝鑰岃繖涓ぇ灏忓氨鏄墍鏈夊瓙鐗╀綋鐨勫ぇ灏忎笌鍙鍖栧尯鍩熺殑宸�
-                                 * 褰揷ontent鐨勫ぇ灏忕瓑浜庢墍鏈夊瓙鐗╀綋鐨勫ぇ灏忔椂锛屽氨鍙互绠�鍖栨搷浣滅洿鎺ョ敤content鐨勫ぇ灏忔潵浠f浛
-                                 */
+        /*scrollrect鐨刵ormallizePosition瀹為檯涓婂氨鏄繖涓湡姝h兘婊戝姩鐨勫尯鍩熺殑澶у皬
+         * 鍦ㄦ粦鍔ㄨ繃绋嬩腑褰掍竴鍖栫殑鍊硷紝鑰岃繖涓ぇ灏忓氨鏄墍鏈夊瓙鐗╀綋鐨勫ぇ灏忎笌鍙鍖栧尯鍩熺殑宸�
+         * 褰揷ontent鐨勫ぇ灏忕瓑浜庢墍鏈夊瓙鐗╀綋鐨勫ぇ灏忔椂锛屽氨鍙互绠�鍖栨搷浣滅洿鎺ョ敤content鐨勫ぇ灏忔潵浠f浛
+         */
         {
             get
             {
@@ -1090,7 +1095,7 @@
                         return 0;
 
                 }
-                  
+
                 else
                 {
                     if (_container != null && _scrollRectTransform != null)
@@ -1098,9 +1103,88 @@
                     else
                         return 0;
                 }
-                   
+
             }
         }
+
+        // 浠呰亰澶╁姛鑳戒娇鐢�
+        public void AddHeight(bool keepPosition, float height)
+        {
+            // 濡傛灉鍚敤寰幆锛屽洖閫�鍒板畬鏁寸殑 _Resize锛屽洜涓哄惊鐜�昏緫澶嶆潅
+            if (loop)
+            {
+                _Resize(keepPosition);
+                return;
+            }
+
+            // 缂撳瓨鍘熷浣嶇疆
+            var originalScrollPosition = _scrollPosition;
+
+            int cellCount = NumberOfCells;
+            if (cellCount == 0)
+            {
+                // 娌℃湁鍗曞厓鏍硷紝璋冪敤 _Resize 澶勭悊
+                _Resize(keepPosition);
+                return;
+            }
+
+            int newCellIndex = cellCount - 1; // 鏂板崟鍏冩牸鐨勭储寮�
+
+            // 妫�鏌ュ唴閮ㄦ暟缁勬槸鍚︿竴鑷达細_cellViewSizeArray 搴旇宸茬粡鍖呭惈浜嗛櫎鏂板崟鍏冩牸澶栫殑鎵�鏈夊崟鍏冩牸
+            if (_cellViewSizeArray.Count != newCellIndex)
+            {
+                // 涓嶄竴鑷达紝鍥為��鍒板畬鏁撮噸缃�
+                _Resize(keepPosition);
+                return;
+            }
+
+            // 璁$畻鏂板崟鍏冩牸鐨勫ぇ灏忥紙鍖呮嫭闂磋窛锛�
+            float newSize = height;
+            newSize += spacing;
+
+            // 娣诲姞鍒板ぇ灏忔暟缁�
+            _cellViewSizeArray.Add(newSize);
+
+            // 鏇存柊鍋忕Щ鏁扮粍
+            float previousOffset = (_cellViewOffsetArray.Count > 0) ? _cellViewOffsetArray.Last() : 0;
+            _cellViewOffsetArray.Add(previousOffset + newSize);
+
+            // 璁剧疆娲诲姩鍗曞厓鏍煎鍣ㄧ殑澶у皬
+            if (scrollDirection == ScrollDirectionEnum.Vertical)
+                _container.sizeDelta = new Vector2(_container.sizeDelta.x, _cellViewOffsetArray.Last() + padding.top + padding.bottom);
+            else
+                _container.sizeDelta = new Vector2(_cellViewOffsetArray.Last() + padding.left + padding.right, _container.sizeDelta.y);
+
+            // 閲嶅缓鍙鍗曞厓鏍�
+            _ResetVisibleCellViews();
+            if (this.Delegate != null)
+            {
+                this.Delegate.OnRebuildComplete();
+            }
+
+            // 濡傛灉闇�瑕佷繚鎸佸師濮嬩綅缃�
+            if (keepPosition)
+            {
+                ScrollPosition = originalScrollPosition;
+            }
+            else
+            {
+                ScrollPosition = 0;
+            }
+
+            // 璁剧疆婊氬姩鏉″彲瑙佹��
+            ScrollbarVisibility = scrollbarVisibility;
+
+            if (!m_IsLoadAll)
+            {
+                m_IsLoadAll = true;
+                if (OnFirstLoadAllEvent != null)
+                {
+                    OnFirstLoadAllEvent();
+                }
+            }
+        }
+
 
         /// <summary>
         /// This function will create an internal list of sizes and offsets to be used in all calculations.
@@ -1157,7 +1241,7 @@
             {
                 _loopFirstScrollPosition = GetScrollPositionForCellViewIndex(_loopFirstCellIndex, CellViewPositionEnum.Before) + (spacing * 0.5f);
                 _loopLastScrollPosition = GetScrollPositionForCellViewIndex(_loopLastCellIndex, CellViewPositionEnum.After) - ScrollRectSize + (spacing * 0.5f);
-               
+
 
                 _loopFirstJumpTrigger = _loopFirstScrollPosition - ScrollRectSize;
                 _loopLastJumpTrigger = _loopLastScrollPosition + ScrollRectSize;
@@ -1399,10 +1483,10 @@
         /// <param name="cellIndex">The index of the cell view</param>
         /// <param name="listPosition">Whether to add the cell to the beginning or the end</param>
         private void _AddCellView(int cellIndex, ListPositionEnum listPosition)
-        {   
+        {
             //閫氳繃鏌愪釜绱㈠紩娣诲姞锛堜粠缂撳啿姹犱腑鍙栵級瀛愮墿浣撳埌_activeCellViews闆嗗悎涓紝骞惰Е鍙戠浉鍏充簨浠�
             //杩欎釜鏂规硶鏈韩涔熶細鏍规嵁浼犺繃鏉ョ殑绱㈠紩鏉ュ垵濮嬪寲CellView
-             
+
             if (NumberOfCells == 0) return;
 
             // get the dataIndex. Modulus is used in case of looping so that the first set of cells are ignored
@@ -1662,7 +1746,7 @@
             _lastScrollbarVisibility = scrollbarVisibility;
             //涓�浜涘彉閲忚繘琛屼簡鍒濆鍖�
 
-            if(OnCompLoad!=null) OnCompLoad();
+            if (OnCompLoad != null) OnCompLoad();
             inited = true;
         }
 
@@ -1672,7 +1756,7 @@
             {
                 // if the reload flag is true, then reload the data
                 ReloadData();//鐞嗚涓婁笉鐢ㄥ湪澶栭儴璋冪敤ReloadData()鍥犱负褰撴垚鍔熻祴鍊糄elegate鍚庤繖涓柟娉曞氨浼氭墽琛屼竴娆�
-                               //浣嗗鏋滄兂鍦╱pdate涔嬪墠鎵ц灏变富鍔ㄨ皟鐢≧eloadData()
+                             //浣嗗鏋滄兂鍦╱pdate涔嬪墠鎵ц灏变富鍔ㄨ皟鐢≧eloadData()
             }
 
             // if the scroll rect size has changed and looping is on,
@@ -1770,7 +1854,7 @@
              */
 
         }
-        
+
         /// <summary>
         /// This is fired by the tweener when the snap tween is completed
         /// </summary>
diff --git a/Main/Config/ConfigManager.cs b/Main/Config/ConfigManager.cs
index c6aa9df..47c6024 100644
--- a/Main/Config/ConfigManager.cs
+++ b/Main/Config/ConfigManager.cs
@@ -70,7 +70,6 @@
             typeof(OrderInfoConfig),
             typeof(PlayerAttrConfig),
             typeof(PlayerFaceConfig),
-            typeof(PriorBundleConfig),
             typeof(RandomNameConfig),
             typeof(SignInConfig),
             typeof(StoreConfig),
@@ -297,8 +296,6 @@
         ClearConfigDictionary<PlayerAttrConfig>();
         // 娓呯┖ PlayerFaceConfig 瀛楀吀
         ClearConfigDictionary<PlayerFaceConfig>();
-        // 娓呯┖ PriorBundleConfig 瀛楀吀
-        ClearConfigDictionary<PriorBundleConfig>();
         // 娓呯┖ RandomNameConfig 瀛楀吀
         ClearConfigDictionary<RandomNameConfig>();
         // 娓呯┖ SignInConfig 瀛楀吀
diff --git a/Main/Config/Configs/ChatBubbleBoxConfig.cs b/Main/Config/Configs/ChatBubbleBoxConfig.cs
index b8216b6..b851bc7 100644
--- a/Main/Config/Configs/ChatBubbleBoxConfig.cs
+++ b/Main/Config/Configs/ChatBubbleBoxConfig.cs
@@ -1,6 +1,6 @@
 锘�//--------------------------------------------------------
 //    [Author]:           YYL
-//    [  Date ]:           2025骞�11鏈�16鏃�
+//    [  Date ]:           2025骞�12鏈�1鏃�
 //--------------------------------------------------------
 
 using System.Collections.Generic;
@@ -30,6 +30,11 @@
 	public int[] InitAttrValueList;
 	public int[] AttrPerStarAddList;
 	public string GetWayString;
+	public int[] LeftOffset;
+	public int[] RightOffset;
+	public int Top;
+	public int[] MyColor;
+	public int[] OtherColor;
 
     public override int LoadKey(string _key)
     {
@@ -104,6 +109,64 @@
 			}
 
 			GetWayString = tables[13];
+
+			if (tables[14].Contains("["))
+			{
+				LeftOffset = JsonMapper.ToObject<int[]>(tables[14]);
+			}
+			else
+			{
+				string[] LeftOffsetStringArray = tables[14].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
+				LeftOffset = new int[LeftOffsetStringArray.Length];
+				for (int i=0;i<LeftOffsetStringArray.Length;i++)
+				{
+					 int.TryParse(LeftOffsetStringArray[i],out LeftOffset[i]);
+				}
+			}
+
+			if (tables[15].Contains("["))
+			{
+				RightOffset = JsonMapper.ToObject<int[]>(tables[15]);
+			}
+			else
+			{
+				string[] RightOffsetStringArray = tables[15].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
+				RightOffset = new int[RightOffsetStringArray.Length];
+				for (int i=0;i<RightOffsetStringArray.Length;i++)
+				{
+					 int.TryParse(RightOffsetStringArray[i],out RightOffset[i]);
+				}
+			}
+
+			int.TryParse(tables[16],out Top); 
+
+			if (tables[17].Contains("["))
+			{
+				MyColor = JsonMapper.ToObject<int[]>(tables[17]);
+			}
+			else
+			{
+				string[] MyColorStringArray = tables[17].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
+				MyColor = new int[MyColorStringArray.Length];
+				for (int i=0;i<MyColorStringArray.Length;i++)
+				{
+					 int.TryParse(MyColorStringArray[i],out MyColor[i]);
+				}
+			}
+
+			if (tables[18].Contains("["))
+			{
+				OtherColor = JsonMapper.ToObject<int[]>(tables[18]);
+			}
+			else
+			{
+				string[] OtherColorStringArray = tables[18].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
+				OtherColor = new int[OtherColorStringArray.Length];
+				for (int i=0;i<OtherColorStringArray.Length;i++)
+				{
+					 int.TryParse(OtherColorStringArray[i],out OtherColor[i]);
+				}
+			}
         }
         catch (Exception exception)
         {
diff --git a/Main/Core/NetworkPackage/ClientPack/CB3_PlayerSocial.meta b/Main/Core/NetworkPackage/ClientPack/CB3_PlayerSocial.meta
new file mode 100644
index 0000000..766e75f
--- /dev/null
+++ b/Main/Core/NetworkPackage/ClientPack/CB3_PlayerSocial.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: de8c89f12e8d05e478b12e42319b8816
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/ClientPack/CB3_PlayerSocial/CB320_tagCSTalk.cs b/Main/Core/NetworkPackage/ClientPack/CB3_PlayerSocial/CB320_tagCSTalk.cs
new file mode 100644
index 0000000..d175daa
--- /dev/null
+++ b/Main/Core/NetworkPackage/ClientPack/CB3_PlayerSocial/CB320_tagCSTalk.cs
@@ -0,0 +1,22 @@
+using UnityEngine;
+using System.Collections;
+
+// B3 20 鑱婂ぉ #tagCSTalk
+
+public class CB320_tagCSTalk : GameNetPackBasic {
+    public byte ChannelType;    // 棰戦亾
+    public ushort Len;
+    public string Content;    //size = Len
+
+    public CB320_tagCSTalk () {
+        combineCmd = (ushort)0x03FE;
+        _cmd = (ushort)0xB320;
+    }
+
+    public override void WriteToBytes () {
+        WriteBytes (ChannelType, NetDataType.BYTE);
+        WriteBytes (Len, NetDataType.WORD);
+        WriteBytes (Content, NetDataType.Chars, Len);
+    }
+
+}
diff --git a/Main/System/Chat/ChatFriendTipCell.cs.meta b/Main/Core/NetworkPackage/ClientPack/CB3_PlayerSocial/CB320_tagCSTalk.cs.meta
similarity index 83%
copy from Main/System/Chat/ChatFriendTipCell.cs.meta
copy to Main/Core/NetworkPackage/ClientPack/CB3_PlayerSocial/CB320_tagCSTalk.cs.meta
index 2e709c7..331ef6f 100644
--- a/Main/System/Chat/ChatFriendTipCell.cs.meta
+++ b/Main/Core/NetworkPackage/ClientPack/CB3_PlayerSocial/CB320_tagCSTalk.cs.meta
@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 68376cb82e4739943aecb4dbbd81a757
+guid: 4fe1fd39a69d5e2428c82f5617b67ced
 MonoImporter:
   externalObjects: {}
   serializedVersion: 2
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HB3_PlayerSocial.meta b/Main/Core/NetworkPackage/DTCFile/ServerPack/HB3_PlayerSocial.meta
new file mode 100644
index 0000000..8101f1b
--- /dev/null
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HB3_PlayerSocial.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 1a5cf4dc5e4cd954487fd817d8d1711e
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HB3_PlayerSocial/DTCB310_tagMCTalk.cs b/Main/Core/NetworkPackage/DTCFile/ServerPack/HB3_PlayerSocial/DTCB310_tagMCTalk.cs
new file mode 100644
index 0000000..f095ca1
--- /dev/null
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HB3_PlayerSocial/DTCB310_tagMCTalk.cs
@@ -0,0 +1,12 @@
+using UnityEngine;
+using System.Collections;
+
+// B3 10 鑱婂ぉ淇℃伅 #tagMCTalk
+
+public class DTCB310_tagMCTalk : DtcBasic {
+    public override void Done(GameNetPackBasic vNetPack) {
+        base.Done(vNetPack);
+        HB310_tagMCTalk vNetData = vNetPack as HB310_tagMCTalk;
+        ChatManager.Instance.UpdateTalk(vNetData);
+    }
+}
diff --git a/Main/System/Chat/ChatFriendTipCell.cs.meta b/Main/Core/NetworkPackage/DTCFile/ServerPack/HB3_PlayerSocial/DTCB310_tagMCTalk.cs.meta
similarity index 83%
rename from Main/System/Chat/ChatFriendTipCell.cs.meta
rename to Main/Core/NetworkPackage/DTCFile/ServerPack/HB3_PlayerSocial/DTCB310_tagMCTalk.cs.meta
index 2e709c7..b808aa5 100644
--- a/Main/System/Chat/ChatFriendTipCell.cs.meta
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HB3_PlayerSocial/DTCB310_tagMCTalk.cs.meta
@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 68376cb82e4739943aecb4dbbd81a757
+guid: ed90c24391805854cb9c7ee1c19d4d8d
 MonoImporter:
   externalObjects: {}
   serializedVersion: 2
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HB3_PlayerSocial/DTCB311_tagMCTalkCacheList.cs b/Main/Core/NetworkPackage/DTCFile/ServerPack/HB3_PlayerSocial/DTCB311_tagMCTalkCacheList.cs
new file mode 100644
index 0000000..531b250
--- /dev/null
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HB3_PlayerSocial/DTCB311_tagMCTalkCacheList.cs
@@ -0,0 +1,12 @@
+using UnityEngine;
+using System.Collections;
+
+// B3 11 鑱婂ぉ缂撳瓨閫氱煡 #tagMCTalkCacheList
+
+public class DTCB311_tagMCTalkCacheList : DtcBasic {
+    public override void Done(GameNetPackBasic vNetPack) {
+        base.Done(vNetPack);
+        HB311_tagMCTalkCacheList vNetData = vNetPack as HB311_tagMCTalkCacheList;
+        ChatManager.Instance.UpdateTalkCacheList(vNetData);
+    }
+}
diff --git a/Main/System/Chat/ChatFriendTipCell.cs.meta b/Main/Core/NetworkPackage/DTCFile/ServerPack/HB3_PlayerSocial/DTCB311_tagMCTalkCacheList.cs.meta
similarity index 83%
copy from Main/System/Chat/ChatFriendTipCell.cs.meta
copy to Main/Core/NetworkPackage/DTCFile/ServerPack/HB3_PlayerSocial/DTCB311_tagMCTalkCacheList.cs.meta
index 2e709c7..1dc81a7 100644
--- a/Main/System/Chat/ChatFriendTipCell.cs.meta
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HB3_PlayerSocial/DTCB311_tagMCTalkCacheList.cs.meta
@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 68376cb82e4739943aecb4dbbd81a757
+guid: c919e25ea044110488ef1d7a7bdf0905
 MonoImporter:
   externalObjects: {}
   serializedVersion: 2
diff --git a/Main/Core/NetworkPackage/DataToCtl/PackageRegedit.cs b/Main/Core/NetworkPackage/DataToCtl/PackageRegedit.cs
index fc27882..c7e1b94 100644
--- a/Main/Core/NetworkPackage/DataToCtl/PackageRegedit.cs
+++ b/Main/Core/NetworkPackage/DataToCtl/PackageRegedit.cs
@@ -126,12 +126,12 @@
         Register(typeof(HA921_tagSCRenameResult), typeof(DTCA921_tagSCRenameResult));
         Register(typeof(HA303_tagSCHorseClassInfo), typeof(DTCA303_tagSCHorseClassInfo));
         Register(typeof(HA304_tagSCHorseSkinInfo), typeof(DTCA304_tagSCHorseSkinInfo));
-
         Register(typeof(HB119_tagSCModelInfo), typeof(DTCB119_tagSCModelInfo));
         Register(typeof(HB126_tagSCTitleInfo), typeof(DTCB126_tagSCTitleInfo));
         Register(typeof(HB127_tagSCChatBoxInfo), typeof(DTCB127_tagSCChatBoxInfo));
         Register(typeof(HB431_tagSCTurnFightRet), typeof(DTCB431_tagSCTurnFightRet));
-
+        Register(typeof(HB310_tagMCTalk), typeof(DTCB310_tagMCTalk));
+        Register(typeof(HB311_tagMCTalkCacheList), typeof(DTCB311_tagMCTalkCacheList));
     }
 
     //涓诲伐绋嬫敞鍐屽皝鍖�
diff --git a/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0201_tagTalkGong.cs b/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0201_tagTalkGong.cs
deleted file mode 100644
index e202acb..0000000
--- a/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0201_tagTalkGong.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-using UnityEngine;
-using System.Collections;
-
-//02 01 公屏#tagTalkGong
-
-
-
-public class H0201_tagTalkGong : GameNetPackBasic {
-
-    public byte NameLen;
-
-    public string Name;    //size = NameLen
-
-    public uint PlayerID;
-
-    public ushort Len;
-
-    public string Content;    //size = Len
-
-    public uint ExtraValue;    //附加值
-
-    public string Extras;    //附加值列表
-
-
-
-    public H0201_tagTalkGong () {
-
-        _cmd = (ushort)0x0201;
-
-    }
-
-
-
-    public override void ReadFromBytes (byte[] vBytes) {
-
-        TransBytes (out NameLen, vBytes, NetDataType.BYTE);
-
-        TransBytes (out Name, vBytes, NetDataType.Chars, NameLen);
-
-        TransBytes (out PlayerID, vBytes, NetDataType.DWORD);
-
-        TransBytes (out Len, vBytes, NetDataType.WORD);
-
-        TransBytes (out Content, vBytes, NetDataType.Chars, Len);
-
-        TransBytes (out ExtraValue, vBytes, NetDataType.DWORD);
-
-        TransBytes (out Extras, vBytes, NetDataType.Chars, 256);
-
-    }
-
-
-
-}
-
diff --git a/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0201_tagTalkGong.cs.meta b/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0201_tagTalkGong.cs.meta
deleted file mode 100644
index fe7c5c4..0000000
--- a/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0201_tagTalkGong.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 59bcc1189c8216d4f873182f0f465e1e
-MonoImporter:
-  externalObjects: {}
-  serializedVersion: 2
-  defaultReferences: []
-  executionOrder: 0
-  icon: {instanceID: 0}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0203_tagTalkBang.cs b/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0203_tagTalkBang.cs
deleted file mode 100644
index cc4dde2..0000000
--- a/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0203_tagTalkBang.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-using UnityEngine;
-using System.Collections;
-
-//02 03 家族频 #tagTalkBang

-

-public class H0203_tagTalkBang : GameNetPackBasic {

-    public byte NameLen;

-    public string Name;    //size = NameLen

-    public uint PlayerID;

-    public ushort Len;

-    public string Content;    //size = Len

-    public uint ExtraValue;    //附加值

-    public string Extras;    //附加值列表

-

-    public H0203_tagTalkBang () {

-        _cmd = (ushort)0x0203;

-    }

-

-    public override void ReadFromBytes (byte[] vBytes) {

-        TransBytes (out NameLen, vBytes, NetDataType.BYTE);

-        TransBytes (out Name, vBytes, NetDataType.Chars, NameLen);

-        TransBytes (out PlayerID, vBytes, NetDataType.DWORD);

-        TransBytes (out Len, vBytes, NetDataType.WORD);

-        TransBytes (out Content, vBytes, NetDataType.Chars, Len);

-        TransBytes (out ExtraValue, vBytes, NetDataType.DWORD);

-        TransBytes (out Extras, vBytes, NetDataType.Chars, 256);

-    }

-

-}

diff --git a/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0203_tagTalkBang.cs.meta b/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0203_tagTalkBang.cs.meta
deleted file mode 100644
index ba53dcc..0000000
--- a/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0203_tagTalkBang.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 48c7cc1b683baa446a59013bc6ae3add
-MonoImporter:
-  externalObjects: {}
-  serializedVersion: 2
-  defaultReferences: []
-  executionOrder: 0
-  icon: {instanceID: 0}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0205_tagTalkDui.cs b/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0205_tagTalkDui.cs
deleted file mode 100644
index 1700637..0000000
--- a/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0205_tagTalkDui.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-using UnityEngine;
-using System.Collections;
-
-//02 05 对频#tagTalkDui

-

-public class H0205_tagTalkDui : GameNetPackBasic {

-    public byte NameLen;

-    public string Name;    //size = NameLen

-    public uint PlayerID;

-    public ushort Len;

-    public string Content;    //size = Len

-    public uint ExtraValue;    //附加值

-    public string Extras;    //附加值列表

-

-    public H0205_tagTalkDui () {

-        _cmd = (ushort)0x0205;

-    }

-

-    public override void ReadFromBytes (byte[] vBytes) {

-        TransBytes (out NameLen, vBytes, NetDataType.BYTE);

-        TransBytes (out Name, vBytes, NetDataType.Chars, NameLen);

-        TransBytes (out PlayerID, vBytes, NetDataType.DWORD);

-        TransBytes (out Len, vBytes, NetDataType.WORD);

-        TransBytes (out Content, vBytes, NetDataType.Chars, Len);

-        TransBytes (out ExtraValue, vBytes, NetDataType.DWORD);

-        TransBytes (out Extras, vBytes, NetDataType.Chars, 256);

-    }

-

-}

diff --git a/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0205_tagTalkDui.cs.meta b/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0205_tagTalkDui.cs.meta
deleted file mode 100644
index e16f375..0000000
--- a/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0205_tagTalkDui.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 3f850a2ad6e22814eaf88e3c521a03e2
-MonoImporter:
-  externalObjects: {}
-  serializedVersion: 2
-  defaultReferences: []
-  executionOrder: 0
-  icon: {instanceID: 0}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0206_tagTalkMi.cs b/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0206_tagTalkMi.cs
deleted file mode 100644
index 5f16bd9..0000000
--- a/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0206_tagTalkMi.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using UnityEngine;
-using System.Collections;
-
-//02 06 密频 #tagTalkMi

-

-public class H0206_tagTalkMi : GameNetPackBasic {

-    public byte TalkType;    //0为默认, 1为1对1聊天用

-    public byte SrcNameLen;

-    public string SrcName;    //size = SrcNameLen

-    public uint PlayerID;

-    public byte ToNameLen;

-    public string ToName;    //size = ToNameLen

-    public uint ToPlayerID;

-    public ushort Len;

-    public string Content;    //size = Len

-    public uint ExtraValue;    //附加值

-    public string Extras;    //附加值列表

-

-    public H0206_tagTalkMi () {

-        _cmd = (ushort)0x0206;

-    }

-

-    public override void ReadFromBytes (byte[] vBytes) {

-        TransBytes (out TalkType, vBytes, NetDataType.BYTE);

-        TransBytes (out SrcNameLen, vBytes, NetDataType.BYTE);

-        TransBytes (out SrcName, vBytes, NetDataType.Chars, SrcNameLen);

-        TransBytes (out PlayerID, vBytes, NetDataType.DWORD);

-        TransBytes (out ToNameLen, vBytes, NetDataType.BYTE);

-        TransBytes (out ToName, vBytes, NetDataType.Chars, ToNameLen);

-        TransBytes (out ToPlayerID, vBytes, NetDataType.DWORD);

-        TransBytes (out Len, vBytes, NetDataType.WORD);

-        TransBytes (out Content, vBytes, NetDataType.Chars, Len);

-        TransBytes (out ExtraValue, vBytes, NetDataType.DWORD);

-        TransBytes (out Extras, vBytes, NetDataType.Chars, 256);

-    }

-

-}

diff --git a/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0206_tagTalkMi.cs.meta b/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0206_tagTalkMi.cs.meta
deleted file mode 100644
index ea097cf..0000000
--- a/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0206_tagTalkMi.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 580543451e143be49b0a211ef8358d69
-MonoImporter:
-  externalObjects: {}
-  serializedVersion: 2
-  defaultReferences: []
-  executionOrder: 0
-  icon: {instanceID: 0}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0207_tagTalkArea.cs b/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0207_tagTalkArea.cs
deleted file mode 100644
index 62c9601..0000000
--- a/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0207_tagTalkArea.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-using UnityEngine;
-using System.Collections;
-
-//02 07 区域频道#tagTalkArea

-

-public class H0207_tagTalkArea : GameNetPackBasic {

-    public byte SrcNameLen;

-    public string SrcName;    //size = SrcNameLen

-    public uint PlayerID;

-    public ushort Len;

-    public string Content;    //size = Len

-    public uint ExtraValue;    //附加值

-    public string Extras;    //附加值列表

-

-    public H0207_tagTalkArea () {

-        _cmd = (ushort)0x0207;

-    }

-

-    public override void ReadFromBytes (byte[] vBytes) {

-        TransBytes (out SrcNameLen, vBytes, NetDataType.BYTE);

-        TransBytes (out SrcName, vBytes, NetDataType.Chars, SrcNameLen);

-        TransBytes (out PlayerID, vBytes, NetDataType.DWORD);

-        TransBytes (out Len, vBytes, NetDataType.WORD);

-        TransBytes (out Content, vBytes, NetDataType.Chars, Len);

-        TransBytes (out ExtraValue, vBytes, NetDataType.DWORD);

-        TransBytes (out Extras, vBytes, NetDataType.Chars, 256);

-    }

-

-}

diff --git a/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0207_tagTalkArea.cs.meta b/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0207_tagTalkArea.cs.meta
deleted file mode 100644
index f052bc1..0000000
--- a/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0207_tagTalkArea.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 6305204e0859d9d4b975cd3417521ffa
-MonoImporter:
-  externalObjects: {}
-  serializedVersion: 2
-  defaultReferences: []
-  executionOrder: 0
-  icon: {instanceID: 0}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0208_tagTalkCountry.cs b/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0208_tagTalkCountry.cs
deleted file mode 100644
index 720f918..0000000
--- a/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0208_tagTalkCountry.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-using UnityEngine;
-using System.Collections;
-
-//02 08 国家频道#tagTalkCountry

-

-public class H0208_tagTalkCountry : GameNetPackBasic {

-    public byte NameLen;

-    public string Name;    //size = NameLen

-    public uint PlayerID;

-    public ushort Len;

-    public string Content;    //size = Len

-    public uint ExtraValue;    //附加值

-    public string Extras;    //附加值列表

-

-    public H0208_tagTalkCountry () {

-        _cmd = (ushort)0x0208;

-    }

-

-    public override void ReadFromBytes (byte[] vBytes) {

-        TransBytes (out NameLen, vBytes, NetDataType.BYTE);

-        TransBytes (out Name, vBytes, NetDataType.Chars, NameLen);

-        TransBytes (out PlayerID, vBytes, NetDataType.DWORD);

-        TransBytes (out Len, vBytes, NetDataType.WORD);

-        TransBytes (out Content, vBytes, NetDataType.Chars, Len);

-        TransBytes (out ExtraValue, vBytes, NetDataType.DWORD);

-        TransBytes (out Extras, vBytes, NetDataType.Chars, 256);

-    }

-

-}

diff --git a/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0208_tagTalkCountry.cs.meta b/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0208_tagTalkCountry.cs.meta
deleted file mode 100644
index 335cdd8..0000000
--- a/Main/Core/NetworkPackage/ServerPack/H02_PlayerTalk/H0208_tagTalkCountry.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 2a22596d78c8a1b428f562758794a03f
-MonoImporter:
-  externalObjects: {}
-  serializedVersion: 2
-  defaultReferences: []
-  executionOrder: 0
-  icon: {instanceID: 0}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/ServerPack/HB3_PlayerSocial/HB310_tagMCTalk.cs b/Main/Core/NetworkPackage/ServerPack/HB3_PlayerSocial/HB310_tagMCTalk.cs
new file mode 100644
index 0000000..f706390
--- /dev/null
+++ b/Main/Core/NetworkPackage/ServerPack/HB3_PlayerSocial/HB310_tagMCTalk.cs
@@ -0,0 +1,43 @@
+using UnityEngine;
+using System.Collections;
+
+// B3 10 鑱婂ぉ淇℃伅 #tagMCTalk
+
+public class HB310_tagMCTalk : GameNetPackBasic {
+    public byte ChannelType;    // 0-涓栫晫锛�1-璺ㄦ湇锛�3- 浠欑洘	
+    public byte NameLen;
+    public string Name;    //size = NameLen
+    public uint PlayerID;
+    public ushort Len;
+    public string Content;    //size = Len
+    public uint BubbleBox;    //鑱婂ぉ姘旀场妗�
+    public ushort LV;    //绛夌骇
+    public byte Job;    //鑱屼笟
+    public byte RealmLV;    //澧冪晫
+    public uint Face;    //鍩烘湰鑴稿瀷
+    public uint FacePic;    //澶村儚妗�
+    public uint TitleID;    //浣╂埓鐨勭О鍙�
+    public uint ServerID;    //鎵�灞炲尯鏈岻D
+
+    public HB310_tagMCTalk () {
+        _cmd = (ushort)0xB310;
+    }
+
+    public override void ReadFromBytes (byte[] vBytes) {
+        TransBytes (out ChannelType, vBytes, NetDataType.BYTE);
+        TransBytes (out NameLen, vBytes, NetDataType.BYTE);
+        TransBytes (out Name, vBytes, NetDataType.Chars, NameLen);
+        TransBytes (out PlayerID, vBytes, NetDataType.DWORD);
+        TransBytes (out Len, vBytes, NetDataType.WORD);
+        TransBytes (out Content, vBytes, NetDataType.Chars, Len);
+        TransBytes (out BubbleBox, vBytes, NetDataType.DWORD);
+        TransBytes (out LV, vBytes, NetDataType.WORD);
+        TransBytes (out Job, vBytes, NetDataType.BYTE);
+        TransBytes (out RealmLV, vBytes, NetDataType.BYTE);
+        TransBytes (out Face, vBytes, NetDataType.DWORD);
+        TransBytes (out FacePic, vBytes, NetDataType.DWORD);
+        TransBytes (out TitleID, vBytes, NetDataType.DWORD);
+        TransBytes (out ServerID, vBytes, NetDataType.DWORD);
+    }
+
+}
diff --git a/Main/System/Chat/ChatFriendTipCell.cs.meta b/Main/Core/NetworkPackage/ServerPack/HB3_PlayerSocial/HB310_tagMCTalk.cs.meta
similarity index 83%
copy from Main/System/Chat/ChatFriendTipCell.cs.meta
copy to Main/Core/NetworkPackage/ServerPack/HB3_PlayerSocial/HB310_tagMCTalk.cs.meta
index 2e709c7..16fa9e6 100644
--- a/Main/System/Chat/ChatFriendTipCell.cs.meta
+++ b/Main/Core/NetworkPackage/ServerPack/HB3_PlayerSocial/HB310_tagMCTalk.cs.meta
@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 68376cb82e4739943aecb4dbbd81a757
+guid: 8be0d9f4eef74044aabaf35d2bd624fb
 MonoImporter:
   externalObjects: {}
   serializedVersion: 2
diff --git a/Main/Core/NetworkPackage/ServerPack/HB3_PlayerSocial/HB311_tagMCTalkCacheList.cs b/Main/Core/NetworkPackage/ServerPack/HB3_PlayerSocial/HB311_tagMCTalkCacheList.cs
new file mode 100644
index 0000000..9abb173
--- /dev/null
+++ b/Main/Core/NetworkPackage/ServerPack/HB3_PlayerSocial/HB311_tagMCTalkCacheList.cs
@@ -0,0 +1,55 @@
+using UnityEngine;
+using System.Collections;
+
+// B3 11 鑱婂ぉ缂撳瓨閫氱煡 #tagMCTalkCacheList
+
+public class HB311_tagMCTalkCacheList : GameNetPackBasic {
+    public byte ChannelType;    // 0-涓栫晫锛�1-璺ㄦ湇锛�3- 浠欑洘	
+    public byte Count;
+    public  tagMCTalkCacheInfo[] InfoList;    //size = Count
+
+    public HB311_tagMCTalkCacheList () {
+        _cmd = (ushort)0xB311;
+    }
+
+    public override void ReadFromBytes (byte[] vBytes) {
+        TransBytes (out ChannelType, vBytes, NetDataType.BYTE);
+        TransBytes (out Count, vBytes, NetDataType.BYTE);
+        InfoList = new tagMCTalkCacheInfo[Count];
+        for (int i = 0; i < Count; i ++) {
+            InfoList[i] = new tagMCTalkCacheInfo();
+            TransBytes (out InfoList[i].NameLen, vBytes, NetDataType.BYTE);
+            TransBytes (out InfoList[i].Name, vBytes, NetDataType.Chars, InfoList[i].NameLen);
+            TransBytes (out InfoList[i].PlayerID, vBytes, NetDataType.DWORD);
+            TransBytes (out InfoList[i].Len, vBytes, NetDataType.WORD);
+            TransBytes (out InfoList[i].Content, vBytes, NetDataType.Chars, InfoList[i].Len);
+            TransBytes (out InfoList[i].BubbleBox, vBytes, NetDataType.DWORD);
+            TransBytes (out InfoList[i].LV, vBytes, NetDataType.WORD);
+            TransBytes (out InfoList[i].Job, vBytes, NetDataType.BYTE);
+            TransBytes (out InfoList[i].RealmLV, vBytes, NetDataType.BYTE);
+            TransBytes (out InfoList[i].Face, vBytes, NetDataType.DWORD);
+            TransBytes (out InfoList[i].FacePic, vBytes, NetDataType.DWORD);
+            TransBytes (out InfoList[i].TitleID, vBytes, NetDataType.DWORD);
+            TransBytes (out InfoList[i].ServerID, vBytes, NetDataType.DWORD);
+            TransBytes (out InfoList[i].TalkTime, vBytes, NetDataType.DWORD);
+        }
+    }
+
+    public class tagMCTalkCacheInfo {
+        public byte NameLen;
+        public string Name;        //size = NameLen
+        public uint PlayerID;
+        public ushort Len;
+        public string Content;        //size = Len
+        public uint BubbleBox;        //鑱婂ぉ姘旀场妗�
+        public ushort LV;        //绛夌骇
+        public byte Job;        //鑱屼笟
+        public byte RealmLV;        //澧冪晫
+        public uint Face;        //鍩烘湰鑴稿瀷
+        public uint FacePic;        //澶村儚妗�
+        public uint TitleID;        //浣╂埓鐨勭О鍙�
+        public uint ServerID;        //鎵�灞炲尯鏈岻D
+        public uint TalkTime;        //璇ヨ亰澶╁彂閫佹椂闂存埑
+    }
+
+}
diff --git a/Main/System/Chat/ChatFriendTipCell.cs.meta b/Main/Core/NetworkPackage/ServerPack/HB3_PlayerSocial/HB311_tagMCTalkCacheList.cs.meta
similarity index 83%
copy from Main/System/Chat/ChatFriendTipCell.cs.meta
copy to Main/Core/NetworkPackage/ServerPack/HB3_PlayerSocial/HB311_tagMCTalkCacheList.cs.meta
index 2e709c7..492e578 100644
--- a/Main/System/Chat/ChatFriendTipCell.cs.meta
+++ b/Main/Core/NetworkPackage/ServerPack/HB3_PlayerSocial/HB311_tagMCTalkCacheList.cs.meta
@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 68376cb82e4739943aecb4dbbd81a757
+guid: 100b4f6d5e20875418941246adf7f06f
 MonoImporter:
   externalObjects: {}
   serializedVersion: 2
diff --git a/Main/Core/ResModule/GameObjectPoolManager.cs b/Main/Core/ResModule/GameObjectPoolManager.cs
index d261352..b9e8433 100644
--- a/Main/Core/ResModule/GameObjectPoolManager.cs
+++ b/Main/Core/ResModule/GameObjectPoolManager.cs
@@ -248,7 +248,7 @@
     /// </summary>
     /// <param name="prefab"></param>
     /// <returns></returns>
-    public GameObjectPool RequestPool(GameObject prefab)
+    public GameObjectPool GetPool(GameObject prefab)
     {
         if (prefab == null)
         {
@@ -286,7 +286,7 @@
             return;
         }
 
-        RequestPool(prefab).Cache(count, _prefabActive);
+        GetPool(prefab).Cache(count, _prefabActive);
     }
 
 
@@ -304,7 +304,7 @@
             return null;
         }
 #endif
-        return RequestPool(prefab).Request();
+        return GetPool(prefab).Request();
     }
 
 
diff --git a/Main/Main.cs b/Main/Main.cs
index 7a45c34..9d6c377 100644
--- a/Main/Main.cs
+++ b/Main/Main.cs
@@ -65,7 +65,6 @@
         managers.Add(CustomizedRechargeModel.Instance);
         managers.Add(CustomizedGiftModel.Instance);
         managers.Add(ChatManager.Instance);
-        managers.Add(ChatBubbleManager.Instance);
         managers.Add(OfficialRankManager.Instance);
         managers.Add(RankModel.Instance);
         managers.Add(PlayerMainDate.Instance);
diff --git a/Main/ResModule/ResManager.cs b/Main/ResModule/ResManager.cs
index 4476aa5..48f61f6 100644
--- a/Main/ResModule/ResManager.cs
+++ b/Main/ResModule/ResManager.cs
@@ -129,6 +129,8 @@
     //needExt 鏄惁闇�瑕佸嚱鏁板唴閮ㄦ坊鍔犲悗缂�
     public T LoadAsset<T>(string directory, string name, bool needExt = true) where T : UnityEngine.Object
     {
+        directory = directory.Replace("\\", "/");
+        name = name.Replace("\\", "/");
         T asset = null;
         //  鐗规畩澶勭悊 鍥犱负鏈変竴灞傚浘闆嗙殑鍏崇郴 directory瑕佷紶鍏ョ殑搴旇鏄痑tlas鐨勫悕瀛�
         if (typeof(T) == typeof(Sprite))
@@ -144,7 +146,6 @@
                 name = name.Substring(name.LastIndexOf("/") + 1);
             }
 
-            directory = directory.Replace("\\", "/");
         }
 
         return LoadAssetInternal<T>(directory, name, needExt);
@@ -234,8 +235,12 @@
             return LoadAssetInternal<Sprite>(atlasName, spriteName);
     }
 
+    //needExt 鏄惁闇�瑕佸嚱鏁板唴閮ㄦ坊鍔犲悗缂�
     public void LoadAssetAsync<T>(string directory, string name, Action<bool, UnityEngine.Object> callBack, bool needExt = true) where T : UnityEngine.Object
     {
+        directory = directory.Replace("\\", "/");
+        name = name.Replace("\\", "/");
+
         //  鐗规畩澶勭悊 鍥犱负鏈変竴灞傚浘闆嗙殑鍏崇郴 directory瑕佷紶鍏ョ殑搴旇鏄痑tlas鐨勫悕瀛�
         if (typeof(T) == typeof(Sprite))
         {
diff --git a/Main/System/AssetVersion/InGameDownTestUtility.cs b/Main/System/AssetVersion/InGameDownTestUtility.cs
index bd23e4a..e9166c4 100644
--- a/Main/System/AssetVersion/InGameDownTestUtility.cs
+++ b/Main/System/AssetVersion/InGameDownTestUtility.cs
@@ -81,5 +81,11 @@
 #endif
         return enable && isReadVesionEx;
     }
+
+
+    public static bool GetDownloadEnable()
+    {
+        return enable;
+    }
 }
 
diff --git a/Main/System/Battle/BattleHUDWin.cs b/Main/System/Battle/BattleHUDWin.cs
index bfbf6fc..bdbbc49 100644
--- a/Main/System/Battle/BattleHUDWin.cs
+++ b/Main/System/Battle/BattleHUDWin.cs
@@ -78,7 +78,7 @@
 
     private void InitializePools()
     {
-        damagePrefabPool = GameObjectPoolManager.Instance.RequestPool(UILoader.LoadPrefab("DamageContent"));
+        damagePrefabPool = GameObjectPoolManager.Instance.GetPool(UILoader.LoadPrefab("DamageContent"));
     }
 
     public void SetBattleField(BattleField _battleField)
diff --git a/Main/System/Chat/ChatBubbleBehaviour.cs b/Main/System/Chat/ChatBubbleBehaviour.cs
index 4d4d25b..9178ac3 100644
--- a/Main/System/Chat/ChatBubbleBehaviour.cs
+++ b/Main/System/Chat/ChatBubbleBehaviour.cs
@@ -1,257 +1,223 @@
 锘縰sing System.Collections;
-using System.Collections.Generic;
-
 using UnityEngine;
 using UnityEngine.UI;
-    [DisallowMultipleComponent]
-    [RequireComponent(typeof(RectTransform))]
-    [ExecuteAlways]
-    public class ChatBubbleBehaviour : MonoBehaviour
+
+[DisallowMultipleComponent]
+[RequireComponent(typeof(RectTransform))]
+[ExecuteAlways]
+public class ChatBubbleBehaviour : MonoBehaviour
+{
+    [SerializeField] Text m_Target;
+    [SerializeField] RectOffset m_Padding;
+    [SerializeField] ImageEx m_BubbleIcon;
+    [SerializeField] UIFrame m_UIFrame;
+    [SerializeField] bool left = false;
+    [SerializeField] bool m_PreferredWidth = false;
+
+    RectTransform m_Rect;
+    RectTransform rect
     {
-        [SerializeField] Text m_Target;
-        [SerializeField] RectOffset m_Padding;
-        [SerializeField] FlipImage m_Flip;
-        [SerializeField] Image m_BubbleIcon;
-        [SerializeField] bool left = false;
-        [SerializeField] bool m_PreferredWidth = false;
-        [SerializeField] RectTransform m_ContainerVoice;
-
-        const float space = 5.0f;
-
-        private int bubbleId = 0;
-
-        RectTransform m_Rect;
-        RectTransform rect
+        get
         {
-            get
+            if (m_Rect == null)
             {
-                if (m_Rect == null)
-                {
-                    m_Rect = transform as RectTransform;
-                }
-                return m_Rect;
+                m_Rect = transform as RectTransform;
             }
+            return m_Rect;
+        }
+    }
+
+    public RectOffset padding
+    {
+        get { return m_Padding; }
+    }
+
+    private void OnEnable()
+    {
+        Refresh();
+    }
+
+    public void DisplayContent(string content, bool _left = false)
+    {
+        if (m_Target == null)
+        {
+            return;
+        }
+        left = _left;
+        m_PreferredWidth = true;
+        var richText = m_Target as RichText;
+        if (richText != null && !left)
+        {
+            richText.AutoNewLine = false;
+        }
+        m_Target.text = content;
+ 
+        if (richText != null)
+        {
+            richText.AutoNewLine = true;
         }
 
-        public RectOffset padding
+        Refresh();
+    }
+    public void DisplaySysBubble(int id, Color color)
+    {
+        ChatBubbleData bubble;
+        if (ChatManager.Instance.TryGetBubble(id, out bubble))
         {
-            get { return m_Padding; }
-        }
+            var bubblePadding = left ? bubble.leftPadding : bubble.rifhtPadding;
+            padding.top = bubblePadding.top;
+            padding.left = bubblePadding.left;
+            padding.right = bubblePadding.right;
+            padding.bottom = bubblePadding.bottom;
 
-        private void OnEnable()
-        {
-            Refresh();
-        }
 
-        public void DisplayContent(string content, bool _left = false)
-        {
-            if (m_Target == null)
+            int resourceType = PhantasmPavilionManager.Instance.GetResourceType(PhantasmPavilionType.ChatBox, id);
+            string resourceValue = PhantasmPavilionManager.Instance.GetResourceValue(PhantasmPavilionType.ChatBox, id);
+            PhantasmPavilionManager.Instance.ShowChatBox(m_BubbleIcon, m_UIFrame, resourceType, resourceValue);
+
+            m_Target.color = color;
+
+            var position = rect.anchoredPosition;
+            if (rect.anchoredPosition != position)
             {
-                return;
-            }
-            left = _left;
-            m_PreferredWidth = true;
-            var targetRect = m_Target.rectTransform;
-            var richText = m_Target as RichText;
-            if (richText != null && !left)
-            {
-                richText.AutoNewLine = false;
-            }
-            m_Target.text = content;
-            if (!left)
-            {
-                if (m_Target.preferredWidth > targetRect.rect.width)
-                {
-                    m_Target.alignment = TextAnchor.UpperLeft;
-                    m_PreferredWidth = false;
-                }
-                else
-                {
-                    m_Target.alignment = TextAnchor.UpperRight;
-                }
-            }
-            if (richText != null)
-            {
-                richText.AutoNewLine = true;
+                rect.anchoredPosition = position;
             }
 
             Refresh();
         }
-
-        public void DisplayBubble(int id)
+    }
+    public void DisplayBubble(int id, int playerId)
+    {
+        ChatBubbleData bubble;
+        if (ChatManager.Instance.TryGetBubble(id, out bubble))
         {
-            bubbleId = id;
-            ChatBubbleManager.ChatBubble bubble;
-            if (ChatBubbleManager.Instance.TryGetBubble(id, out bubble))
+            var bubblePadding = left ? bubble.leftPadding : bubble.rifhtPadding;
+            padding.top = bubblePadding.top;
+            padding.left = bubblePadding.left;
+            padding.right = bubblePadding.right;
+            padding.bottom = bubblePadding.bottom;
+
+
+            int resourceType = PhantasmPavilionManager.Instance.GetResourceType(PhantasmPavilionType.ChatBox, id);
+            string resourceValue = PhantasmPavilionManager.Instance.GetResourceValue(PhantasmPavilionType.ChatBox, id);
+            PhantasmPavilionManager.Instance.ShowChatBox(m_BubbleIcon, m_UIFrame, resourceType, resourceValue);
+
+            if (playerId == PlayerDatas.Instance.PlayerId)
             {
-                var bubblePadding = left ? bubble.leftPadding : bubble.rifhtPadding;
-                padding.top = bubblePadding.top;
-                padding.left = bubblePadding.left;
-                padding.right = bubblePadding.right;
-                padding.bottom = bubblePadding.bottom;
-
-                bool requireFlip = false;
-                var iconKey = bubble.GetBubbleIcon(left, ref requireFlip);
-                
-                //m_BubbleIcon.SetSprite(iconKey);
-
-
-                UIFrame frame = m_BubbleIcon.GetComponent<UIFrame>();
-                if (UIFrameMgr.Inst.ContainsDynamicImage(iconKey))
-                {
-                    if (frame == null)
-                        frame = m_BubbleIcon.gameObject.AddComponent<UIFrame>();
-                    frame.ResetFrame(iconKey);
-                    frame.enabled = true;
-                }
-                else
-                {
-                    if (frame != null)
-                        frame.enabled = false;
-                    m_BubbleIcon.SetSprite(iconKey);
-                }
-                m_Flip.flipHorizontal = requireFlip;
-                m_Target.color = bubble.color;
-
-                var position = rect.anchoredPosition;
-                // TODO YYL
-                // ChatBubbleBoxConfig config = ChatBubbleBoxConfig.Get(bubbleId);
-                // position.y = -config.top;
-                if (rect.anchoredPosition != position)
-                {
-                    rect.anchoredPosition = position;
-                }
-
-                Refresh();
-            }
-        }
-
-        [ExecuteAlways]
-        private void LateUpdate()
-        {
-            Refresh();
-        }
-
-        void Refresh()
-        {
-            if (m_Target == null)
-            {
-                return;
-            }
-            bool nullContent = string.IsNullOrEmpty(m_Target.text);
-
-            var targetRect = m_Target.rectTransform;
-            var sizeDelta = targetRect.sizeDelta;
-
-            var width = m_PreferredWidth || !Application.isPlaying ? m_Target.preferredWidth : sizeDelta.x;
-            if (nullContent)
-            {
-                width = 0f;
-            }
-            var height = sizeDelta.y;
-            if (nullContent)
-            {
-                height = 0;
-            }
-
-            if (m_ContainerVoice != null)
-            {
-                width = Mathf.Max(m_ContainerVoice.sizeDelta.x, width);
-                height += m_ContainerVoice.sizeDelta.y;
-                if (!nullContent)
-                {
-                    height += space;
-                }
-            }
-
-            sizeDelta.x = width + m_Padding.left + m_Padding.right;
-            sizeDelta.y = height + m_Padding.top + m_Padding.bottom;
-            if (sizeDelta != rect.sizeDelta)
-            {
-                rect.sizeDelta = sizeDelta;
-            }
-
-            SetAnchor(m_Target.rectTransform);
-            if (m_ContainerVoice != null)
-            {
-                SetAnchor(m_ContainerVoice);
-            }
-
-            float top = padding.top;
-            Vector2 position = Vector2.zero;
-            position.x = left ? padding.left : -padding.right;
-            if (m_ContainerVoice != null)
-            {
-                position.y = -top;
-                if (m_ContainerVoice.anchoredPosition != position)
-                {
-                    m_ContainerVoice.anchoredPosition = position;
-                }
-                top = top + m_ContainerVoice.sizeDelta.y;
-                top += space;
-            }
-            position.y = -top;
-            if (targetRect.anchoredPosition != position)
-            {
-                targetRect.anchoredPosition = position;
-            }
-        }
-
-        void SetAnchor(RectTransform targetRect)
-        {
-            if (!left)
-            {
-                if (targetRect.anchorMin != Vector2.one)
-                {
-                    targetRect.anchorMin = Vector2.one;
-                }
-                if (targetRect.anchorMax != Vector2.one)
-                {
-                    targetRect.anchorMax = Vector2.one;
-                }
-                if (targetRect.pivot != Vector2.one)
-                {
-                    targetRect.pivot = Vector2.one;
-                }
+                m_Target.color = bubble.myColor;
             }
             else
             {
-                if (targetRect.anchorMin != Vector2.up)
-                {
-                    targetRect.anchorMin = Vector2.up;
-                }
-                if (targetRect.anchorMax != Vector2.up)
-                {
-                    targetRect.anchorMax = Vector2.up;
-                }
-                if (targetRect.pivot != Vector2.up)
-                {
-                    targetRect.pivot = Vector2.up;
-                }
+                m_Target.color = bubble.otherColor;
             }
+
+            var position = rect.anchoredPosition;
+            position.y = -bubble.top;
+            if (rect.anchoredPosition != position)
+            {
+                rect.anchoredPosition = position;
+            }
+
+            Refresh();
+        }
+    }
+
+    [ExecuteAlways]
+    private void LateUpdate()
+    {
+        Refresh();
+    }
+
+    void Refresh()
+    {
+        if (m_Target == null)
+        {
+            return;
+        }
+        bool nullContent = string.IsNullOrEmpty(m_Target.text);
+
+        var targetRect = m_Target.rectTransform;
+        var sizeDelta = targetRect.sizeDelta;
+
+        var width = m_PreferredWidth || !Application.isPlaying ? m_Target.preferredWidth : sizeDelta.x;
+        if (nullContent)
+        {
+            width = 0f;
+        }
+        var height = sizeDelta.y;
+        if (nullContent)
+        {
+            height = 0;
         }
 
-        public float GetBubbleHeight(string content, ArrayList list)
+        sizeDelta.x = width + m_Padding.left + m_Padding.right;
+        sizeDelta.y = height + m_Padding.top + m_Padding.bottom;
+        if (sizeDelta != rect.sizeDelta)
         {
-            if (m_Target is RichText)
-            {
-                (m_Target as RichText).SetExtenalData(list);
-            }
-            m_Target.text = content;
-            var height = m_Target.preferredHeight;
-            bool nullContent = string.IsNullOrEmpty(content);
-            if (nullContent)
-            {
-                height = 0f;
-            }
-            if (m_ContainerVoice != null)
-            {
-                height += m_ContainerVoice.sizeDelta.y;
-                if (!nullContent)
-                {
-                    height += space;
-                }
-            }
-            return height + padding.top + padding.bottom;
+            rect.sizeDelta = sizeDelta;
         }
-    }
\ No newline at end of file
+
+        SetAnchor(m_Target.rectTransform);
+
+        float top = padding.top;
+        Vector2 position = Vector2.zero;
+        position.x = left ? padding.left : -padding.right;
+
+        position.y = -top;
+        if (targetRect.anchoredPosition != position)
+        {
+            targetRect.anchoredPosition = position;
+        }
+    }
+
+    void SetAnchor(RectTransform targetRect)
+    {
+        if (!left)
+        {
+            if (targetRect.anchorMin != Vector2.one)
+            {
+                targetRect.anchorMin = Vector2.one;
+            }
+            if (targetRect.anchorMax != Vector2.one)
+            {
+                targetRect.anchorMax = Vector2.one;
+            }
+            if (targetRect.pivot != Vector2.one)
+            {
+                targetRect.pivot = Vector2.one;
+            }
+        }
+        else
+        {
+            if (targetRect.anchorMin != Vector2.up)
+            {
+                targetRect.anchorMin = Vector2.up;
+            }
+            if (targetRect.anchorMax != Vector2.up)
+            {
+                targetRect.anchorMax = Vector2.up;
+            }
+            if (targetRect.pivot != Vector2.up)
+            {
+                targetRect.pivot = Vector2.up;
+            }
+        }
+    }
+
+    public float GetBubbleHeight(string content, ArrayList list)
+    {
+        if (m_Target is RichText)
+        {
+            (m_Target as RichText).SetExtenalData(list);
+        }
+        m_Target.text = content;
+        var height = m_Target.preferredHeight;
+        bool nullContent = string.IsNullOrEmpty(content);
+        if (nullContent)
+        {
+            height = 0f;
+        }
+        //Debug.Log($"GetBubbleHeight {height + padding.top + padding.bottom} height {height} padding.top {padding.top} padding.bottom {padding.bottom}");
+        return height + padding.top + padding.bottom;
+    }
+}
\ No newline at end of file
diff --git a/Main/System/Chat/ChatBubbleManager.cs b/Main/System/Chat/ChatBubbleManager.cs
deleted file mode 100644
index df138fb..0000000
--- a/Main/System/Chat/ChatBubbleManager.cs
+++ /dev/null
@@ -1,174 +0,0 @@
-锘縰sing System;
-using System.Collections.Generic;
-
-using UnityEngine;
-    
-    public class ChatBubbleManager : GameSystemManager<ChatBubbleManager>
-    {
-        public Dictionary<int, ChatBubble> chatBubbles = new Dictionary<int, ChatBubble>();
-
-        public event Action chatBubbleStateRefresh;
-
-        bool serverInited = false;
-        public override void Init()
-        {
-            PlayerDatas.Instance.playerDataRefreshEvent += PlayerDataRefreshInfoEvent;
-        }
-
-        public override void Release()
-        {
-            PlayerDatas.Instance.playerDataRefreshEvent -= PlayerDataRefreshInfoEvent;
-        }
-
-        public void OnBeforePlayerDataInitialize()
-        {
-            bubblesIfo.Clear();
-            serverInited = false;
-        }
-
-        public void OnPlayerLoginOk()
-        {
-            serverInited = true;
-        }
-
-        private void PlayerDataRefreshInfoEvent(PlayerDataType refreshType)
-        {
-            if (refreshType == PlayerDataType.ExAttr10 && serverInited)
-            {
-                SysNotifyMgr.Instance.ShowTip("ChangeBubbleSuccess");
-            }
-        }
-
-        public bool TryGetBubble(int id, out ChatBubble bubble)
-        {
-            return chatBubbles.TryGetValue(id, out bubble);
-        }
-
-        public bool IsBubbleGot(int id)
-        {
-            ChatBubble bubble;
-            if (TryGetBubble(id, out bubble))
-            {
-                // var config = ChatBubbleBoxConfig.Get(id);
-                bool got = false;
-
-                if (bubblesIfo.ContainsKey(id) && bubblesIfo[id].State == 1)
-                {
-                    got = true;
-                }
-                // if (!got && config.NeedLV != 0)
-                // {
-                //     return PlayerDatas.Instance.baseData.LV >= config.NeedLV;
-                // }
-                return got;
-            }
-            return false;
-        }
-
-        #region 鏈嶅姟绔暟鎹�
-
-        //鑱婂ぉ姘旀场妗�
-        public struct BubbleBox
-        {
-            public int State;        //鏄惁宸叉縺娲�
-            public int EndTime;        //鍒版湡鏃堕棿鎴筹紝0涓烘案涔�
-            public int Star;        //鏄熺骇
-        }
-
-        public Dictionary<int, BubbleBox> bubblesIfo = new Dictionary<int, BubbleBox>();
-
-        // public void UpdateBubbleState(HA717_tagMCChatBubbleBoxState package)
-        // {
-        //     List<int> list = null;
-        //     if (serverInited)
-        //     {
-        //         list = new List<int>();
-        //         foreach (var id in chatBubbles.Keys)
-        //         {
-        //             if (!IsBubbleGot(id))
-        //             {
-        //                 list.Add(id);
-        //             }
-        //         }
-        //     }
-
-        //     for (int i = 0; i < package.Count; i++)
-        //     {
-        //         var info = package.BoxList[i];
-        //         bubblesIfo[info.BoxID] = new BubbleBox()
-        //         {
-        //             State = info.State,
-        //             EndTime = (int)info.EndTime,
-        //             Star = info.Star,
-        //         };
-        //     }
-
-        //     if (serverInited)
-        //     {
-        //         if (list != null)
-        //         {
-        //             for (int i = 0; i < list.Count; i++)
-        //             {
-        //                 if (IsBubbleGot(list[i]))
-        //                 {
-        //                     SendUseBubble(list[i]);
-        //                     break;
-        //                 }
-        //             }
-        //         }
-        //     }
-        //     if (chatBubbleStateRefresh != null)
-        //     {
-        //         chatBubbleStateRefresh();
-        //     }
-        // }
-
-        public void SendUseBubble(int id)
-        {
-            if (!IsBubbleGot(id))
-            {
-                return;
-            }
-            if (id == PlayerDatas.Instance.baseData.chatBox)
-            {
-                return;
-            }
-            // CA230_tagCMSetChatBubbleBox pak = new CA230_tagCMSetChatBubbleBox();
-            // pak.BubbleBoxType = (byte)id;
-            // GameNetSystem.Instance.SendInfo(pak);
-        }
-        #endregion
-
-        public struct ChatBubble
-        {
-            public int id;
-            public RectOffset leftPadding;
-            public RectOffset rifhtPadding;
-            public Color32 color;
-
-            public string GetBubbleIcon(bool left, ref bool isFlip)
-            {
-                return string.Empty;
-                // var config = ChatBubbleBoxConfig.Get(id);
-                // isFlip = false;
-                // if (left)
-                // {
-                //     if (string.IsNullOrEmpty(config.leftBubbleIcon))
-                //     {
-                //         isFlip = true;
-                //         return config.rightBubbleIcon;
-                //     }
-                //     return config.leftBubbleIcon;
-                // }
-                // else
-                // {
-                //     if (string.IsNullOrEmpty(config.rightBubbleIcon))
-                //     {
-                //         isFlip = true;
-                //         return config.leftBubbleIcon;
-                //     }
-                //     return config.rightBubbleIcon;
-                // }
-            }
-        }
-    }
diff --git a/Main/System/Chat/ChatBubbleManager.cs.meta b/Main/System/Chat/ChatBubbleManager.cs.meta
deleted file mode 100644
index 888e932..0000000
--- a/Main/System/Chat/ChatBubbleManager.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: cd3d8f0df84e9824aaf1c2cbb4c033b0
-MonoImporter:
-  externalObjects: {}
-  serializedVersion: 2
-  defaultReferences: []
-  executionOrder: 0
-  icon: {instanceID: 0}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 
diff --git a/Main/System/Chat/ChatBulletItem.cs b/Main/System/Chat/ChatBulletItem.cs
new file mode 100644
index 0000000..d1a527e
--- /dev/null
+++ b/Main/System/Chat/ChatBulletItem.cs
@@ -0,0 +1,128 @@
+using System;
+using UnityEngine;
+using UnityEngine.UI;
+using DG.Tweening;
+using System.Collections;
+
+[RequireComponent(typeof(RectTransform))]
+public class ChatBulletItem : MonoBehaviour
+{
+    [SerializeField] ImageEx contentImage;
+    [SerializeField] RichText contentText;
+
+    [SerializeField] ImageEx sysImage;
+    [SerializeField] RichText sysText;
+    // 鑳屾櫙鍥惧乏鍙崇殑棰濆鐣欑櫧 (x:宸﹁竟璺�, y:鍙宠竟璺�)
+    [SerializeField] Vector2 padding = new Vector2(50f, 50f);
+    [SerializeField] Vector2 sysPadding = new Vector2(70f, 70f);
+    private RectTransform rectTrans;
+    private RectTransform imageRect;
+    private RectTransform imageSysRect;
+    private GameObject sourcePrefab;
+    private Tweener moveTweener;
+    private Action<ChatBulletItem> onFinishCallback;
+
+    private void Awake()
+    {
+        rectTrans = GetComponent<RectTransform>();
+        imageRect = contentImage.rectTransform;
+        imageSysRect = sysImage.rectTransform;
+    }
+
+    public void Init(bool isSys, string content, ArrayList infoList, Color color, float speed, Vector2 startPos, float leftBoundary, GameObject prefab, Action<ChatBulletItem> onFinish)
+    {
+        if (rectTrans == null)
+            rectTrans = GetComponent<RectTransform>();
+        contentImage.SetActive(!isSys);
+        sysImage.SetActive(isSys);
+
+        if (infoList != null)
+        {
+            contentText.SetExtenalData(infoList);
+            sysText.SetExtenalData(infoList);
+        }
+
+        contentText.text = content;
+        sysText.text = content;
+        contentText.color = color;
+        sysText.color = color;
+        sourcePrefab = prefab;
+        onFinishCallback = onFinish;
+
+        // 鑾峰彇鏂囨湰鍐呭鐨勭悊鎯冲搴�
+        //LayoutRebuilder.ForceRebuildLayoutImmediate(contentText.rectTransform);
+        float txtWidth = contentText.preferredWidth;
+
+        float totalWidth = 0;
+        float currentHeight = 0;
+        if (!isSys)
+        {
+            // 璁$畻鑳屾櫙鍥剧殑鎬诲搴� = 鏂囨湰瀹� + 宸﹀彸Padding
+            totalWidth = txtWidth + padding.x + padding.y;
+            // 淇濇寔鍘熸湁鐨勯珮搴�
+            currentHeight = rectTrans.sizeDelta.y;
+            // 璁剧疆鑳屾櫙鍥�(ContentImage)鐨勫ぇ灏�
+            if (imageRect != null)
+            {
+                imageRect.sizeDelta = new Vector2(totalWidth, currentHeight);
+            }
+        }
+        else
+        {
+            // 璁$畻鑳屾櫙鍥剧殑鎬诲搴� = 鏂囨湰瀹� + 宸﹀彸Padding
+            totalWidth = txtWidth + sysPadding.x + sysPadding.y;
+            // 鍥剧墖鐨勯珮搴�
+            currentHeight = 39;
+            // 璁剧疆鑳屾櫙鍥�(ContentImage)鐨勫ぇ灏�
+            if (imageSysRect != null)
+            {
+                imageSysRect.sizeDelta = new Vector2(totalWidth, currentHeight);
+            }
+        }
+
+
+        // 璁剧疆鏍硅妭鐐圭殑澶у皬
+        rectTrans.sizeDelta = new Vector2(totalWidth, currentHeight);
+        // 璁剧疆鍒濆浣嶇疆
+        rectTrans.anchoredPosition = startPos;
+
+        // 姝ゆ椂 rectTrans.rect.width 宸茬粡鏄垜浠墜鍔ㄨ缃殑 totalWidth 浜�
+        float endX = leftBoundary - totalWidth;
+        float distance = Mathf.Abs(startPos.x - endX);
+        float duration = distance / speed;
+
+        // 5. 寮�濮嬬Щ鍔�
+        moveTweener?.Kill();
+        moveTweener = rectTrans.DOAnchorPosX(endX, duration)
+            .SetEase(Ease.Linear)
+            .OnComplete(Recycle);
+    }
+
+    //ChatBulletItem鏈�鍙充晶鐨刋鍧愭爣
+    public float GetRightEdgeX()
+    {
+        return rectTrans.anchoredPosition.x + rectTrans.rect.width;
+    }
+
+    private void Recycle()
+    {
+        moveTweener?.Kill();
+        moveTweener = null;
+
+        onFinishCallback?.Invoke(this);
+
+        if (GameObjectPoolManager.Instance != null && sourcePrefab != null)
+        {
+            GameObjectPoolManager.Instance.GetPool(sourcePrefab).Release(this.gameObject);
+        }
+        else
+        {
+            Destroy(gameObject);
+        }
+    }
+
+    private void OnDestroy()
+    {
+        moveTweener?.Kill();
+    }
+}
\ No newline at end of file
diff --git a/Main/System/Chat/ChatFriendTipCell.cs.meta b/Main/System/Chat/ChatBulletItem.cs.meta
similarity index 83%
copy from Main/System/Chat/ChatFriendTipCell.cs.meta
copy to Main/System/Chat/ChatBulletItem.cs.meta
index 2e709c7..fb0fac9 100644
--- a/Main/System/Chat/ChatFriendTipCell.cs.meta
+++ b/Main/System/Chat/ChatBulletItem.cs.meta
@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 68376cb82e4739943aecb4dbbd81a757
+guid: 351513bf72cdb364994c539f4dfae3bd
 MonoImporter:
   externalObjects: {}
   serializedVersion: 2
diff --git a/Main/System/Chat/ChatBulletView.cs b/Main/System/Chat/ChatBulletView.cs
new file mode 100644
index 0000000..95f8804
--- /dev/null
+++ b/Main/System/Chat/ChatBulletView.cs
@@ -0,0 +1,130 @@
+using System.Collections;
+using UnityEngine;
+using UnityEngine.UI;
+
+public class ChatBulletView : MonoBehaviour
+{
+    [SerializeField] GameObject bulletPrefab; // 蹇呴』璧嬪�奸鍒朵綋
+    [SerializeField] RectTransform bulletContainer;
+
+    [SerializeField] float bulletSpeed = 150f;
+    [SerializeField] float position1Y = 220f;
+    [SerializeField] Vector2 randomYRange = new Vector2(200f, -200);
+    [SerializeField] float safeSpacing = 20f;
+    [SerializeField] Color defaultColor = Color.white;
+
+    private ChatBulletItem lastItemOnPos1;
+    private float screenWidth;
+    private float screenLeftX;
+    ChatManager manager { get { return ChatManager.Instance; } }
+    private void Awake()
+    {
+        screenWidth = 750;
+        screenLeftX = -screenWidth / 2;
+        GameObjectPoolManager.Instance.CacheGameObject(bulletPrefab, 10, false);
+    }
+
+    private void Start()
+    {
+        ChatManager.Instance.OnUpdateTalkEvent += OnUpdateTalkEvent;
+    }
+
+    private void OnDestroy()
+    {
+        ChatManager.Instance.OnUpdateTalkEvent -= OnUpdateTalkEvent;
+    }
+
+    private void OnUpdateTalkEvent(ChatChannel channel, TalkData data)
+    {
+        if (!ChatManager.Instance.GetBulletSetting(channel))
+            return;
+        // 0-绯荤粺 1-鏃ユ湡 2-鑷繁 3-鍏朵粬鐜╁
+        int type = manager.GetTalkDataType(data);
+        if (type == 1)
+            return;
+        SpawnBullet(channel, type == 0, type == 0 ? data.Content : GetBulletContent(channel, data), data.InfoList);
+    }
+
+    private string GetBulletContent(ChatChannel channel, TalkData data)
+    {
+        switch (channel)
+        {
+            case ChatChannel.World:
+                string serverName = ServerListCenter.Instance.GetServerName((int)data.ServerID);
+                return Language.Get("Chat16", serverName, data.Name, data.Content);
+            case ChatChannel.Guild:
+                return Language.Get("Chat16", Language.Get("ChatTab1"), data.Name, data.Content);
+            default:
+                return data.Content;
+        }
+    }
+
+
+    private void SpawnBullet(ChatChannel channel, bool isSys, string content, ArrayList infoList)
+    {
+        if (bulletPrefab == null || GameObjectPoolManager.Instance == null)
+            return;
+
+        // 銆愬叧閿慨鏀广�戜粠鐗瑰畾瀵硅薄姹犺幏鍙栧璞�
+        GameObject obj = GameObjectPoolManager.Instance.RequestGameObject(bulletPrefab);
+
+        // 銆愰噸瑕併�戝璞℃睜绠$悊鍣ㄤ細鎶婄埗鑺傜偣璁句负null锛岃繖閲屽繀椤婚噸璁惧洖UI瀹瑰櫒
+        obj.transform.SetParent(bulletContainer, false);
+        obj.transform.localScale = Vector3.one;
+        obj.SetActive(true);
+
+        ChatBulletItem item = obj.GetComponent<ChatBulletItem>();
+        if (item == null)
+            item = obj.AddComponent<ChatBulletItem>();
+
+        Color color = GetChannelColor(channel);
+        float spawnY = CalculateSpawnY();
+        Vector2 startPos = new Vector2(screenWidth / 2, spawnY);
+
+        item.Init(isSys, content, infoList, color, bulletSpeed, startPos, screenLeftX, bulletPrefab, OnBulletFinish);
+
+        if (Mathf.Abs(spawnY - position1Y) < 1f)
+        {
+            lastItemOnPos1 = item;
+        }
+    }
+
+    private float CalculateSpawnY()
+    {
+        bool pos1Available = true;
+
+        if (lastItemOnPos1 != null && lastItemOnPos1.gameObject.activeSelf)
+        {
+            // 涓婁竴鏉″脊骞曡繕娌″畬鍏ㄧ寮�鍙充晶瀹夊叏鍖�
+            float spawnX = screenWidth / 2;
+            if (lastItemOnPos1.GetRightEdgeX() > spawnX - safeSpacing)
+            {
+                pos1Available = false;
+            }
+        }
+
+        if (pos1Available)
+        {
+            return position1Y;
+        }
+        else
+        {
+            return Random.Range(randomYRange.x, randomYRange.y);
+        }
+    }
+
+    private void OnBulletFinish(ChatBulletItem item)
+    {
+        if (item == lastItemOnPos1)
+        {
+            lastItemOnPos1 = null;
+        }
+    }
+
+    private Color GetChannelColor(ChatChannel channel)
+    {
+        if (!manager.chatChannelBulletColorDict.TryGetValue(channel, out var color))
+            return defaultColor;
+        return color;
+    }
+}
\ No newline at end of file
diff --git a/Main/System/Chat/ChatFriendTipCell.cs.meta b/Main/System/Chat/ChatBulletView.cs.meta
similarity index 83%
copy from Main/System/Chat/ChatFriendTipCell.cs.meta
copy to Main/System/Chat/ChatBulletView.cs.meta
index 2e709c7..bf62570 100644
--- a/Main/System/Chat/ChatFriendTipCell.cs.meta
+++ b/Main/System/Chat/ChatBulletView.cs.meta
@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 68376cb82e4739943aecb4dbbd81a757
+guid: 1bc8c847ece8a9440bb8422960593260
 MonoImporter:
   externalObjects: {}
   serializedVersion: 2
diff --git a/Main/System/Chat/ChatCenter.cs b/Main/System/Chat/ChatCenter.cs
deleted file mode 100644
index db034a0..0000000
--- a/Main/System/Chat/ChatCenter.cs
+++ /dev/null
@@ -1,544 +0,0 @@
-锘縰sing System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Text;
-using System.Text.RegularExpressions;
-using UnityEngine;
-using Cysharp.Threading.Tasks;
-
-    
-    public class ChatCenter : Singleton<ChatCenter>
-    {
-        public int talkRechargeLimmit;
-        public int talkLevelLimmit;
-
-        public void Init()
-        {
-            ParseConfig();
-            //var _uiframe = UIFrameMgr.Inst;
-            // ChatSetting.Instance.RefreshChatSetAct += RefreshChatSetAct;
-            // TimeMgr.Instance.OnSyntonyEvent += OnSyntonyEvent;
-            // VoiceHttpRequest.Instance.samplesDecodecComplete += SamplesDecodecComplete;
-            UIManager.Instance.OnOpenWindow += WindowAfterOpenEvent;
-            // StageLoad.Instance.onStageLoadFinish += OnStageLoadFinish;
-            // PrepareHandler.Instance.OnPrepareEnd += OnPrepareEnd;
-
-            var time = bandTime;
-            banTimeArray[0] = time.Year;
-            banTimeArray[1] = time.Month;
-            banTimeArray[2] = time.Day;
-            banTimeArray[3] = time.Hour;
-            banTimeArray[4] = time.Minute;
-            banTimeArray[5] = time.Second;
-        }
-
-        public void UnInit()
-        {
-
-        }
-
-        bool serverInited = false;
-
-        public int chatCharacterLimit { get; private set; }
-        public int bugleItem { get; private set; }
-        public bool beforeDungeon { get; private set; }
-        public List<ChatInfoType> chatChannels { get; private set; }
-
-        public int chatInputLength { get; set; }
-        public StringBuilder m_EncodeBuilder = new StringBuilder();
-        void ParseConfig()
-        {
-            chatCharacterLimit = int.Parse(FuncConfigConfig.Get("MessageLength").Numerical1);
-            // var _funcCfg = FuncConfigConfig.Get("BugleItem");
-            // bugleItem = int.Parse(_funcCfg.Numerical1);
-            chatChannels = new List<ChatInfoType>();
-            chatChannels.Add(ChatInfoType.System);
-            chatChannels.Add(ChatInfoType.World);
-            chatChannels.Add(ChatInfoType.CrossServer);
-            chatChannels.Add(ChatInfoType.Area);
-            chatChannels.Add(ChatInfoType.Team);
-            chatChannels.Add(ChatInfoType.Invite);
-            chatChannels.Add(ChatInfoType.Trumpet);
-            chatChannels.Add(ChatInfoType.Fairy);
-            chatChannels.Add(ChatInfoType.Friend);
-            chatChannels.Add(ChatInfoType.default1);
-
-            // var config = FuncConfigConfig.Get("ClientChatBan");
-            // banCheckSecond = int.Parse(config.Numerical1);
-            // repeatCountLimit = int.Parse(config.Numerical2);
-            // maliceCheckCount = int.Parse(config.Numerical3);
-            // maliceLimitCount = int.Parse(config.Numerical4);
-            // var array = ConfigParse.GetMultipleStr<int>(config.Numerical5);
-            // singleBanSecond = array[0];
-            // maxBanSecond = array[1];
-
-            var config = FuncConfigConfig.Get("LocalChatHistoryCount");
-            if (config != null)
-            {
-                LocalChatHistory.localSaveCount = int.Parse(config.Numerical1);
-                if (!string.IsNullOrEmpty(config.Numerical2))
-                {
-                    LocalChatHistory.localChatKeepHour = int.Parse(config.Numerical2);
-                }
-            }
-
-            config = FuncConfigConfig.Get("TalkLimit");
-            talkRechargeLimmit = int.Parse(config.Numerical1);
-            talkLevelLimmit = int.Parse(config.Numerical2);
-        }
-
-        public event Action<string, bool, bool> UpdateChatValueEvent;
-        public void ChangeChatValue(string _msg, bool _add, bool _force)
-        {
-            if (UpdateChatValueEvent != null)
-            {
-                UpdateChatValueEvent(_msg, _add, _force);
-            }
-        }
-
-        public event Action UpdateChatType;
-        public void ChangeChatType()
-        {
-            if (UpdateChatType != null)
-            {
-                UpdateChatType();
-            }
-        }
-
-        public event Action UpdateChatContent;
-        public void UpdateChatContentPos()
-        {
-            if (UpdateChatContent != null)
-            {
-                UpdateChatContent();
-            }
-        }
-
-        public ChatData GetChatData(ChatInfoType _type, int _index, int _pteChatId = 0)
-        {
-            ChatData chat = null;
-            if (_type == ChatInfoType.Friend)
-            {
-                var _list = ChatManager.Instance.GetChatInfo(_pteChatId == 0 ? ChatManager.Instance.PteChatID : _pteChatId);
-                if (_list == null || _index >= _list.Count)
-                {
-                    return null;
-                }
-                chat = _list[_index];
-            }
-            else
-            {
-                List<ChatData> _list = ChatManager.Instance.GetChatInfo(_type);
-                if (_list == null || _index >= _list.Count)
-                {
-                    return null;
-                }
-                chat = _list[_index];
-            }
-            return chat;
-        }
-
-        public const int RecentlyChatNum = 8;
-        public List<RecentlyChat> recentlyChats = new List<RecentlyChat>(RecentlyChatNum);
-        public event Action RecentlyChatChangeEvent;
-        public RecentlyChat recentlyChat = null;
-
-        public RecentlyChat SaveRecentlyChat(string _chat)
-        {
-            if (ChatManager.Instance.IsInviteChat(_chat)
-                || Regex.IsMatch(_chat, ChatManager.KILL_IDENTIFY))
-            {
-                return null;
-            }
-            if (s_VoiceRegex.IsMatch(_chat))
-            {
-                _chat = s_VoiceRegex.Replace(_chat, string.Empty);
-            }
-            if (recentlyChats.FindIndex((x) =>
-             {
-                 return x.display.Equals(_chat);
-             }) != -1)
-            {
-                return null;
-            }
-            if (recentlyChats.Count >= RecentlyChatNum)
-            {
-                var _old = recentlyChats[0];
-                recentlyChats.RemoveAt(0);
-                _old = null;
-            }
-            var _recentlyChat = new RecentlyChat(_chat);
-            recentlyChats.Add(_recentlyChat);
-            if (RecentlyChatChangeEvent != null)
-            {
-                RecentlyChatChangeEvent();
-            }
-            return _recentlyChat;
-        }
-
-        public void OnBeforePlayerDataInitialize()
-        {
-            recentlyChat = null;
-            serverInited = false;
-            m_VoiceChatDict.Clear();
-        }
-
-        public void OnSwitchAccount()
-        {
-
-        }
-
-
-        public class RecentlyChat
-        {
-            public string display = string.Empty;
-            public List<string> itemInfos = new List<string>();
-            public List<int> itemIndexs = new List<int>();
-            public List<string> itemNames = new List<string>();
-
-            public RecentlyChat()
-            {
-
-            }
-
-            public RecentlyChat(string _chat)
-            {
-                display = _chat;
-            }
-
-            public void Add(string _name, string _itemInfo)
-            {
-                itemNames.Add(_name);
-                itemInfos.Add(_itemInfo);
-            }
-
-            public void Reset()
-            {
-                itemIndexs.Clear();
-                for (int i = 0; i < itemInfos.Count; i++)
-                {
-                    itemIndexs.Add(i);
-                }
-            }
-
-            public override string ToString()
-            {
-                return LitJson.JsonMapper.ToJson(this);
-            }
-
-            public static bool TryParse(string json, out RecentlyChat chat)
-            {
-                chat = null;
-                try
-                {
-                    chat = LitJson.JsonMapper.ToObject<RecentlyChat>(json);
-                }
-                catch (Exception e)
-                {
-                    Debug.LogError(e.StackTrace + e.Message);
-                    return false;
-                }
-                return chat != null;
-            }
-        }
-
-        public static readonly Regex s_VoiceRegex = new Regex("<v=([0-9]+)_([0-9]+)>");
-        private Dictionary<int, VoiceChat> m_VoiceChatDict = new Dictionary<int, VoiceChat>();
-
-        public class VoiceChat
-        {
-            public ChatInfoType chatType;
-            public int index;
-            public int toPlayer;
-            public long tick;
-            public byte length;
-            public bool translate = false;
-            public byte[] encode;
-            public string result = string.Empty;
-        }
-
-        public void SetVoice(int _instance, ChatInfoType _type, float _length, int _toPlayer = 0)
-        {
-            if (!m_VoiceChatDict.ContainsKey(_instance))
-            {
-                VoiceChat _chat = new VoiceChat()
-                {
-                    chatType = _type,
-                    index = _instance,
-                    toPlayer = _toPlayer,
-                    tick = TimeUtility.ServerNow.Ticks,
-                    translate = false,
-                    encode = null,
-                    length = (byte)Mathf.Min((int)(_length * 10), 100),
-                };
-                m_VoiceChatDict.Add(_instance, _chat);
-            }
-        }
-
-        public void OnPlayerLoginOk()
-        {
-            serverInited = true;
-        }
-
-        private void WindowAfterOpenEvent(UIBase win)
-        {
-            CheckChatFloatOpen();
-            if (win is MainWin)
-            {
-                Co_CheckAfterCollect().Forget();
-            }
-        }
-
-        public bool IsShowChatFloat()
-        {
-            return !UIManager.Instance.IsOpened<LoadingWin>();
-            // if (!UIManager.Instance.IsOpened<LoadingWin>())
-            //     return true;
-            // return false;
-        }
-
-        private void CheckChatFloatOpen()
-        {
-            if (IsShowChatFloat())
-            {
-                if (!UIManager.Instance.IsOpened<ChatFloatWin>())
-                {
-                    UIManager.Instance.OpenWindow<ChatFloatWin>();
-                }
-            }
-        }
-
-        bool openChatAfterCollect = false;
-        // private void OnPrepareEnd(int playerId, int type)
-        // {
-        //     if (playerId == PlayerDatas.Instance.baseData.PlayerID
-        //         && type == 0 && PlayerDatas.Instance.baseData.MapID == 31230)
-        //     {
-        //         openChatAfterCollect = true;
-        //     }
-        //     CheckOpenChatAfterCollect();
-        // }
-
-        async UniTask Co_CheckAfterCollect()
-        {
-            await UniTask.Yield();
-            CheckOpenChatAfterCollect();
-        }
-
-        void CheckOpenChatAfterCollect()
-        {
-            if (!openChatAfterCollect)
-            {
-                return;
-            }
-            if (PlayerDatas.Instance.baseData.MapID != 31230)
-            {
-                return;
-            }
-            if (!UIManager.Instance.IsOpened<MainWin>()
-                /*TODO YYL|| NewBieCenter.Instance.inGuiding*/)
-            {
-                return;
-            }
-            openChatAfterCollect = false;
-
-            if (!UIManager.Instance.IsOpened<ChatWin>())
-            {
-                ChatManager.Instance.presentChatType = ChatInfoType.Fairy;
-                UIManager.Instance.OpenWindow<ChatWin>();
-            }
-        }
-
-
-        public string SetChatExtra()
-        {
-            var vipLevel = PlayerDatas.Instance.baseData.VIPLv;
-            var job = PlayerDatas.Instance.baseData.Job;
-            var bubbleId = PlayerDatas.Instance.baseData.chatBox;
-            var serverGroupId = PlayerDatas.Instance.baseData.ServerGroupId;
-            return StringUtility.Contact(vipLevel.ToString().PadLeft(2, '0'), 0, job,
-                bubbleId.ToString().PadLeft(2, '0'), serverGroupId.ToString().PadLeft(7, '0'));
-        }
-
-        public void HandleChatBanned(ChatInfoType channel, string message, int toPlayer)
-        {
-            if (IsChatBanned || clientBanned)
-            {
-                var playerId = PlayerDatas.Instance.baseData.PlayerID;
-                var playerName = UIHelper.ServerStringTrim(PlayerDatas.Instance.baseData.PlayerName);
-                switch (channel)
-                {
-                    case ChatInfoType.World:
-                        ChatManager.Instance.RevChatInfo(new H0201_tagTalkGong()
-                        {
-                            Content = message,
-                            Extras = SetChatExtra(),
-                            PlayerID = playerId,
-                            Name = playerName,
-                        });
-                        break;
-                    case ChatInfoType.Area:
-                        ChatManager.Instance.RevChatInfo(new H0207_tagTalkArea()
-                        {
-                            Content = message,
-                            Extras = SetChatExtra(),
-                            PlayerID = playerId,
-                            SrcName = playerName,
-                        });
-                        break;
-                    case ChatInfoType.CrossServer:
-                        ChatManager.Instance.RevChatInfo(new H0208_tagTalkCountry()
-                        {
-                            Content = message,
-                            Extras = SetChatExtra(),
-                            PlayerID = playerId,
-                            Name = playerName,
-                        });
-                        break;
-                    case ChatInfoType.Team:
-                        ChatManager.Instance.RevChatInfo(new H0205_tagTalkDui()
-                        {
-                            PlayerID = playerId,
-                            Name = playerName,
-                            Content = message,
-                            Extras = SetChatExtra(),
-                        });
-                        break;
-                    case ChatInfoType.Fairy:
-                        ChatManager.Instance.RevChatInfo(new H0203_tagTalkBang()
-                        {
-                            PlayerID = playerId,
-                            Content = message,
-                            Extras = SetChatExtra(),
-                            Name = playerName,
-                        });
-                        break;
-                    case ChatInfoType.Friend:
-                        ChatManager.Instance.RevChatInfo(new H0206_tagTalkMi()
-                        {
-                            PlayerID = playerId,
-                            SrcName = playerName,
-                            Content = message,
-                            Extras = SetChatExtra(),
-                            ToPlayerID = (uint)toPlayer,
-                            ToName = string.Empty,
-                            TalkType = 1,
-                        });
-                        break;
-                    case ChatInfoType.default1:
-                        ChatManager.Instance.RevChatInfo(new HA707_tagMCPyTalk()
-                        {
-                            Content = message,
-                            Extras = SetChatExtra(),
-                            PlayerID = playerId,
-                            Name = playerName,
-                        });
-                        break;
-                }
-            }
-        }
-
-        public void ServerForbidenChat(bool value)
-        {
-            if (value)
-            {
-                serverForbidenChat = true;
-            }
-        }
-        private bool m_serverForbidenChat;
-        bool serverForbidenChat {
-            //get { return LocalSave.GetBool("ServerForbidenChat"); }
-            //set { LocalSave.SetBool("ServerForbidenChat", value); }
-            get { return m_serverForbidenChat; }
-            set { m_serverForbidenChat = value; }
-        }
-
-        public bool IsChatBanned {
-            get {
-                var value = PlayerDatas.Instance.extersion.forbidenTalk;
-                //澧炲姞鍒ゆ柇鏄惁璁惧绂佽█
-                if (LocalSave.GetBool("ServerForbidenChatDevice1", false) || value > 0)
-                    return true;
-                return false;
-            }
-        }
-
-        public bool clientBanned {
-            get {
-                return false;
-                //var time = new DateTime(banTimeArray[0], banTimeArray[1], banTimeArray[2],
-                //    banTimeArray[3], banTimeArray[4], banTimeArray[5]);
-                //return TimeUtility.ServerNow < time;
-            }
-        }
-
-        public int banCheckSecond = 60;
-        public int repeatCountLimit = 5;
-        public int maliceCheckCount = 10;
-        public int maliceLimitCount = 5;
-        public int singleBanSecond = 1;
-        public int maxBanSecond = 1;
-
-    public int banSecond;
-        // {
-        //     get { return LocalSave.GetInt("ClientChatBanSecond", 0); }
-        //     set {
-        //         LocalSave.SetInt("ClientChatBanSecond", value);
-        //     }
-        // }
-
-        private int[] banTimeArray = new int[6];
-    private DateTime bandTime;
-        // {
-        //     get {
-        //         var timeArray = LocalSave.GetIntArray("ClientChatBanTime");
-        //         if (null == timeArray)
-        //         {
-        //             return TimeUtility.OriginalTime;
-        //         }
-        //         else
-        //         {
-        //             return new DateTime(timeArray[0], timeArray[1], timeArray[2], timeArray[3], timeArray[4], timeArray[5]);
-        //         }
-        //     }
-        //     set {
-        //         banTimeArray[0] = value.Year;
-        //         banTimeArray[1] = value.Month;
-        //         banTimeArray[2] = value.Day;
-        //         banTimeArray[3] = value.Hour;
-        //         banTimeArray[4] = value.Minute;
-        //         banTimeArray[5] = value.Second;
-        //         LocalSave.SetIntArray("ClientChatBanTime", banTimeArray);
-        //     }
-        // }
-
-        public void ChatClientBan()
-        {
-//            if (!clientBanned)
-//            {
-//                var time = TimeUtility.ServerNow;
-//                var second = Mathf.Min(maxBanSecond, banSecond + singleBanSecond);
-//                banSecond = second;
-//                bandTime = time.AddTicks(second * TimeSpan.TicksPerSecond);
-//#if !UNITY_EDITOR
-//                OperationLogCollect.Instance.BugReport(Language.Get("ClientBanTitle"),
-//                    Language.Get("ClientBanContent", banSecond));
-//#endif
-//            }
-        }
-
-        public bool IsClientBan(ChatInfoType chatType)
-        {
-            return false;
-            //if (!clientBanned)
-            //{
-            //    return false;
-            //}
-            //if (chatType == ChatInfoType.Fairy)
-            //{
-            //    var model = ModelCenter.Instance.GetModel<DailyQuestModel>();
-            //    return model.GetQuestState((int)DailyQuestType.FairyFeast) != DailyQuestModel.DailyQuestState.Normal;
-            //}
-            //return clientBanned;
-        }
-    }
diff --git a/Main/System/Chat/ChatCenter.cs.meta b/Main/System/Chat/ChatCenter.cs.meta
deleted file mode 100644
index efc2554..0000000
--- a/Main/System/Chat/ChatCenter.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: dda4314f0337ba442ac1a05b0cdd2350
-MonoImporter:
-  externalObjects: {}
-  serializedVersion: 2
-  defaultReferences: []
-  executionOrder: 0
-  icon: {instanceID: 0}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 
diff --git a/Main/System/Chat/ChatChannelCell.cs b/Main/System/Chat/ChatChannelCell.cs
deleted file mode 100644
index a64b4dd..0000000
--- a/Main/System/Chat/ChatChannelCell.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-锘縰sing System.Collections;
-using System.Collections.Generic;
-using UnityEngine;
-using UnityEngine.UI;
-
-using EnhancedUI.EnhancedScroller;
-    public class ChatChannelCell : ScrollerUI
-    {
-        [SerializeField] Image m_Select;
-        [SerializeField] Text m_ChannelName;
-
-        private static Color unselectedColor = new Color32(237, 161, 13, 255);
-        private static Color selectedColor = new Color32(255, 244, 205, 255);
-
-        public override void Refresh(CellView cell)
-        {
-            var _type = (ChatInfoType)cell.index;
-            if (_type == ChatInfoType.Friend)
-            {
-                m_ChannelName.text = Language.Get("PlayerDetail_PrivateChat");
-            }
-            else
-            {
-                m_ChannelName.text = Language.Get(StringUtility.Contact("ChatType_", _type.ToString()));
-            }
-            m_Select.SetActive(_type == ChatManager.Instance.presentChatType);
-            m_ChannelName.color = _type == ChatManager.Instance.presentChatType ? selectedColor : unselectedColor;
-        }
-    }
-
diff --git a/Main/System/Chat/ChatChannelCell.cs.meta b/Main/System/Chat/ChatChannelCell.cs.meta
deleted file mode 100644
index 0a83415..0000000
--- a/Main/System/Chat/ChatChannelCell.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 6c06ce11d5cc99840934ed275c4f8859
-MonoImporter:
-  externalObjects: {}
-  serializedVersion: 2
-  defaultReferences: []
-  executionOrder: 0
-  icon: {instanceID: 0}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 
diff --git a/Main/System/Chat/ChatContentBehaviour.cs b/Main/System/Chat/ChatContentBehaviour.cs
deleted file mode 100644
index 225367c..0000000
--- a/Main/System/Chat/ChatContentBehaviour.cs
+++ /dev/null
@@ -1,534 +0,0 @@
-锘縰sing System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Text.RegularExpressions;
-using UnityEngine;
-using UnityEngine.UI;
-using EnhancedUI.EnhancedScroller;
-
-// TODO YYL
-
-    public class ChatContentBehaviour : MonoBehaviour
-    {
-        [SerializeField] ScrollerController m_ChatContentControl;
-        [SerializeField] RichText m_DestSysText;
-        [SerializeField] RichText m_DestTipText;
-        [SerializeField] RectTransform m_ContaienrNewInfo;
-        [SerializeField] Text m_NewInfoText;
-        [SerializeField] Button m_NewInfoBtn;
-        [SerializeField] Button m_LockAreaBtn;
-        [SerializeField] Image m_LockAreaCheck;
-        [SerializeField] RectTransform m_ContainerDisplay;
-        [SerializeField] RectTransform m_ContainerPrivateChatRemind;
-        [SerializeField] RectTransform m_Scroller;
-
-        [SerializeField, Header("閿佸畾褰撳墠鍖哄煙姣斾緥"), Range(0, 1)] float m_Percent = 0.3f;
-
-        [SerializeField] ChatPlayerMineCell m_ChatMineCell;
-        [SerializeField] ChatPlayerOtherCell m_ChatOtherCell;
-        // [SerializeField] ChatMineVoiceCell m_ChatMineVoiceCell;
-        // [SerializeField] ChatOtherVoiceCell m_ChatOtherVoiceCell;
-
-        private ChatInfoType m_ChatType = ChatInfoType.System;
-        public ChatInfoType chatType
-        {
-            get
-            {
-                return m_ChatType;
-            }
-            set
-            {
-                bool isChange = m_ChatType != value;
-                ResetNewInfo();
-                m_ChatType = value;
-                DisplayChatContent();
-                if (isChange)
-                {
-                    DisplayChatRemind();
-                }
-            }
-        }
-
-        public ScrollerController chatContentControl
-        {
-            get
-            {
-                return m_ChatContentControl;
-            }
-        }
-
-        private int cacheChatCount = 0;
-        private bool onCheckArea = false;
-
-        // FriendsModel friendModel
-        // {
-        //     get { return ModelCenter.Instance.GetModel<FriendsModel>(); }
-        // }
-
-        private void Awake()
-        {
-            m_ChatContentControl.OnGetDynamicSize += OnGetChatDynamicSize;
-            m_NewInfoBtn.onClick.AddListener(OnNewInfo);
-            m_LockAreaBtn.onClick.AddListener(OnLockAreaBtn);
-            m_ChatContentControl.mScrollRect.onValueChanged.AddListener(OnScrollValChange);
-
-            if (m_DestSysText.font == null)
-            {
-                m_DestSysText.font = FontUtility.preferred;
-            }
-            if (m_DestTipText.font == null)
-            {
-                m_DestTipText.font = FontUtility.preferred;
-            }
-        }
-
-        private void OnEnable()
-        {
-            DisplayChatContent();
-            DisplayChatRemind();
-            ChatManager.OnRefreshChat += OnRefreshChat;
-            ChatManager.OnRefreshPteChat += OnRefreshPteChat;
-            ChatManager.OnRefreshSelf += OnRefreshSelf;
-            ChatManager.Instance.OnPteChatChangeEvent += OnPteChatChangeEvent;
-            ChatCenter.Instance.UpdateChatContent += UpdateChatContent;
-            PlayerDatas.Instance.playerDataRefreshEvent += PlayerDataRefreshInfoEvent;
-            // friendModel.RefreshFriendCntEvent += RefreshFriendCntEvent;
-            // friendModel.RefreshFriendModel += DisplayChatRemind;
-            ResetNewInfo();
-            UpdateChatContent();
-            if (m_ChatType == ChatInfoType.Friend)
-            {
-                DisplayChatContent();
-                JumpPteChatBottom();
-            }
-        }
-
-        private void OnPteChatChangeEvent()
-        {
-            if (m_ChatType == ChatInfoType.Friend)
-            {
-                DisplayChatContent();
-                DisplayChatRemind();
-                JumpPteChatBottom();
-            }
-        }
-
-        private void OnRefreshSelf(ChatData data)
-        {
-            ChatCenter.Instance.ChangeChatValue(string.Empty, false, false);
-            ChatManager.Instance.itemPlaceList.Clear();
-            if (m_ChatType == ChatInfoType.Friend)
-            {
-                JumpPteChatBottom();
-            }
-            else
-            {
-                ChatManager.Instance.lockUpdate = false;
-            }
-            UpdateChatContent();
-        }
-
-        private void OnRefreshPteChat(ChatFriendData data)
-        {
-            if (data == null)
-            {
-                return;
-            }
-            if (data.toPlayer != ChatManager.Instance.PteChatID && data.player != ChatManager.Instance.PteChatID)
-            {
-                return;
-            }
-            DisplayChatContent(true);
-            float _displaySize = 0;
-            if (m_ChatContentControl.mScrollRect != null)
-            {
-                _displaySize = m_ChatContentControl.mScrollRect.content.sizeDelta.y;
-            }
-            if (data.player == PlayerDatas.Instance.baseData.PlayerID)
-            {
-                OnRefreshSelf(data);
-            }
-            else if (ChatManager.Instance.lockUpdate && _displaySize > m_ChatContentControl.m_Scorller.ScrollRectSize)
-            {
-                cacheChatCount++;
-                cacheChatCount = Mathf.Min(cacheChatCount, 999);
-                m_NewInfoText.text = Language.Get("ChatNewWord", cacheChatCount);
-                m_ContaienrNewInfo.SetActive(true);
-            }
-        }
-
-        private void OnScrollValChange(Vector2 _pos)
-        {
-            if (m_ChatContentControl.mScrollRect.verticalNormalizedPosition < 0.1f && m_ChatType == ChatInfoType.Friend)
-            {
-                ResetNewInfo();
-            }
-            if (m_ChatContentControl.m_Scorller._ScrollSize <= 0 || m_ChatType == ChatInfoType.Friend)
-            {
-                return;
-            }
-            float _value = m_Percent / m_ChatContentControl.m_Scorller._ScrollSize * m_ChatContentControl.m_Scorller.ScrollRectSize;
-            if (_pos.y <= _value)
-            {
-                if (ChatManager.Instance.lockUpdate && !onCheckArea)
-                {
-                    ChatManager.Instance.lockUpdate = false;
-                    UpdateLockAreaState();
-                    ResetNewInfo();
-                }
-                onCheckArea = true;
-            }
-            else
-            {
-                if (!ChatManager.Instance.lockUpdate)
-                {
-                    ChatManager.Instance.lockUpdate = true;
-                    UpdateChatContent();
-                }
-                onCheckArea = false;
-            }
-        }
-
-        private void OnLockAreaBtn()
-        {
-            ChatManager.Instance.lockUpdate = !ChatManager.Instance.lockUpdate;
-            UpdateChatContent();
-        }
-
-        private void OnRefreshChat(ChatInfoType _type)
-        {
-            if (_type == m_ChatType)
-            {
-                DisplayChatContent(true);
-                float _displaySize = 0;
-                if (m_ChatContentControl.mScrollRect != null)
-                {
-                    _displaySize = m_ChatContentControl.mScrollRect.content.sizeDelta.y;
-                }
-                if (ChatManager.Instance.lockUpdate && _displaySize > m_ChatContentControl.m_Scorller.ScrollRectSize)
-                {
-                    cacheChatCount++;
-                    cacheChatCount = Mathf.Min(cacheChatCount, 999);
-                    m_NewInfoText.text = Language.Get("ChatNewWord", cacheChatCount);
-                    m_ContaienrNewInfo.SetActive(true);
-                }
-            }
-        }
-
-        private void ResetNewInfo()
-        {
-            cacheChatCount = 0;
-            if (m_ContaienrNewInfo.gameObject.activeSelf)
-            {
-                m_ContaienrNewInfo.SetActive(false);
-            }
-        }
-
-        private void DisplayChatContent(bool _keep = false)
-        {
-            float _offset = KeepArea();
-
-            m_ChatContentControl.Refresh();
-
-            if (m_ChatType != ChatInfoType.Friend)
-            {
-                List<ChatData> _list = ChatManager.Instance.GetChatInfo(m_ChatType);
-                if (_list != null)
-                {
-                    for (int i = 0; i < _list.Count; i++)
-                    {
-                        switch (_list[i].type)
-                        {
-                            case ChatInfoType.World:
-                            case ChatInfoType.Area:
-                            case ChatInfoType.CrossServer:
-                            case ChatInfoType.Team:
-                            case ChatInfoType.Trumpet:
-                            case ChatInfoType.Fairy:
-                            case ChatInfoType.default1:
-                            case ChatInfoType.default2:
-                                ChatUeseData data = _list[i] as ChatUeseData;
-                                if (data.detailType == ChatInfoType.FairyQuestion
-                                    || data.detailType == ChatInfoType.FairyTip
-                                    || data.detailType == ChatInfoType.TeamTip
-                                    || data.detailType == ChatInfoType.default2)
-                                {
-                                    m_ChatContentControl.AddCell(ScrollerDataType.Extra1, i);
-                                }
-                                else
-                                {
-                                    if (data.IsSound)
-                                    {
-                                        m_ChatContentControl.AddCell(data.player == PlayerDatas.Instance.PlayerId ?
-                                            ScrollerDataType.Extra2 : ScrollerDataType.Extra3, i);
-                                        break;
-                                    }
-                                    if (data.player == PlayerDatas.Instance.baseData.PlayerID)
-                                    {
-                                        m_ChatContentControl.AddCell(ScrollerDataType.Header, i);
-                                    }
-                                    else
-                                    {
-                                        m_ChatContentControl.AddCell(ScrollerDataType.Normal, i);
-                                    }
-                                }
-                                break;
-                            case ChatInfoType.Invite:
-                            case ChatInfoType.System:
-                                {
-                                    m_ChatContentControl.AddCell(ScrollerDataType.Tail, i);
-                                }
-                                break;
-                        }
-                    }
-                }
-            }
-            else
-            {
-                List<ChatFriendData> _list = ChatManager.Instance.GetChatInfo(ChatManager.Instance.PteChatID);
-                if (_list != null)
-                {
-                    for (int i = 0; i < _list.Count; i++)
-                    {
-                        if (_list[i].IsSound)
-                        {
-                            m_ChatContentControl.AddCell(_list[i].player == PlayerDatas.Instance.PlayerId ?
-                                            ScrollerDataType.Extra2 : ScrollerDataType.Extra3, i);
-                            continue;
-                        }
-                        if (Regex.IsMatch(_list[i].content, ChatManager.KILL_IDENTIFY))
-                        {
-                            m_ChatContentControl.AddCell(ScrollerDataType.Tail, i);
-                            continue;
-                        }
-                        if (_list[i].player == PlayerDatas.Instance.baseData.PlayerID)
-                        {
-                            m_ChatContentControl.AddCell(ScrollerDataType.Header, i);
-                        }
-                        else
-                        {
-                            m_ChatContentControl.AddCell(ScrollerDataType.Normal, i);
-                        }
-                    }
-                }
-            }
-
-            m_ChatContentControl.Restart();
-
-            if (_keep && ChatManager.Instance.lockUpdate)
-            {
-                m_ChatContentControl.JumpIndex(-_offset, 0, EnhancedUI.EnhancedScroller.EnhancedScroller.TweenType.immediate);
-            }
-
-            m_LockAreaBtn.SetActive(m_ChatType != ChatInfoType.Friend);
-        }
-
-        private void DisplayChatRemind()
-        {
-            if (m_ContainerPrivateChatRemind != null)
-            {
-                // bool requireRemind = false;
-                // var _dict = friendModel.GetFriendInfoDict((byte)GroupType.RecentContact);
-                // if (m_ChatType == ChatInfoType.Friend)
-                // {
-                //     if (WindowCenter.Instance.IsOpen<ChatWin>())
-                //     {
-                //         if (((_dict != null && _dict.Count > 0) ||
-                //         friendModel.tempFriendData != null) && ChatManager.Instance.PteChatID > 0)
-                //         {
-                //             requireRemind = true;
-                //         }
-                //     }
-                //     else
-                //     {
-                //         requireRemind = true;
-                //     }
-                // }
-                // var displayAreaHeight = m_ContainerDisplay.rect.height;
-                // m_ContainerPrivateChatRemind.SetActive(requireRemind);
-                // if (requireRemind)
-                // {
-                //     displayAreaHeight = m_ContainerDisplay.rect.height - m_ContainerPrivateChatRemind.rect.height;
-                // }
-                // m_Scroller.sizeDelta = m_Scroller.sizeDelta.SetY(displayAreaHeight);
-            }
-        }
-
-        float KeepArea()
-        {
-            if (m_ChatContentControl.GetNumberOfCells(m_ChatContentControl.m_Scorller) == ChatManager.Instance.CHAT_INFO_CNT)
-            {
-                var count = 0;
-                if (m_ChatType == ChatInfoType.Friend)
-                {
-                    var list = ChatManager.Instance.GetChatInfo(ChatManager.Instance.PteChatID);
-                    count = list == null ? 0 : list.Count;
-                }
-                else
-                {
-                    var list = ChatManager.Instance.GetChatInfo(m_ChatType);
-                    count = list == null ? 0 : list.Count;
-                }
-                if (count == ChatManager.Instance.CHAT_INFO_CNT)
-                {
-                    var first_size = m_ChatContentControl.GetCellSize(0);
-                    return first_size;
-                }
-            }
-            return 0;
-        }
-
-        private void SoundReceiveEvent(ChatInfoType _type, int _index)
-        {
-            if (m_ChatType != _type)
-            {
-                return;
-            }
-            m_ChatContentControl.RefreshSingleCellView(_index);
-        }
-
-        private bool OnGetChatDynamicSize(ScrollerDataType _type, int _index, out float _height)
-        {
-            _height = 0;
-            ChatData chat = null;
-            if (m_ChatType == ChatInfoType.Friend)
-            {
-                var _list = ChatManager.Instance.GetChatInfo(ChatManager.Instance.PteChatID);
-                if (_list == null || _index >= _list.Count)
-                {
-                    return false;
-                }
-                chat = _list[_index];
-            }
-            else
-            {
-                List<ChatData> _list = ChatManager.Instance.GetChatInfo(m_ChatType);
-                if (_list == null || _index >= _list.Count)
-                {
-                    return false;
-                }
-                chat = _list[_index];
-            }
-            if (chat == null)
-            {
-                return false;
-            }
-            switch (_type)
-            {
-                case ScrollerDataType.Header:
-                    _height = m_ChatMineCell.GetHeight(chat.content, chat.infoList);
-                    return true;
-                case ScrollerDataType.Normal:
-                    _height = m_ChatOtherCell.GetHeight(chat.content, chat.infoList);
-                    return true;
-                case ScrollerDataType.Extra1:
-                case ScrollerDataType.Tail:
-                    _height = 30;
-                    break;
-                // case ScrollerDataType.Extra2:
-                    // _height = m_ChatMineVoiceCell.GetHeight(chat.content, chat.infoList);
-                    // return true;
-                // case ScrollerDataType.Extra3:
-                    // _height = m_ChatOtherVoiceCell.GetHeight(chat.content, chat.infoList);
-                    // return true;
-                default:
-                    return false;
-            }
-            OnGetChatDynamicHeight(chat.content, ref _height, _type, chat.infoList);
-            return true;
-        }
-
-        private void OnGetChatDynamicHeight(string _content, ref float _height, ScrollerDataType _type, ArrayList _infoList)
-        {
-            float _textHeight = 0;
-            if (_type == ScrollerDataType.Tail)
-            {
-                m_DestSysText.SetExtenalData(_infoList);
-                m_DestSysText.text = _content;
-                _textHeight = Mathf.Max(m_DestSysText.preferredHeight, m_DestSysText.fontSize);
-                _height += Mathf.Max(0, _textHeight - 23);
-            }
-            else if (_type == ScrollerDataType.Extra1)
-            {
-                m_DestTipText.SetExtenalData(_infoList);
-                m_DestTipText.text = _content;
-                _textHeight = Mathf.Max(m_DestTipText.preferredHeight, m_DestTipText.fontSize);
-                _height += Mathf.Max(0, _textHeight - 23);
-            }
-        }
-
-        private void UpdateChatContent()
-        {
-            UpdateLockAreaState();
-            if (!ChatManager.Instance.lockUpdate)
-            {
-                chatContentControl.ResetScrollPos();
-                ResetNewInfo();
-            }
-        }
-
-        private void UpdateLockAreaState()
-        {
-            chatContentControl.lockType = ChatManager.Instance.lockUpdate ? EnhanceLockType.KeepVertical : EnhanceLockType.LockVerticalBottom;
-            m_LockAreaCheck.SetActive(ChatManager.Instance.lockUpdate);
-        }
-
-        private void OnNewInfo()
-        {
-            if (m_ChatType != ChatInfoType.Friend)
-            {
-                ChatManager.Instance.lockUpdate = false;
-            }
-            else
-            {
-                JumpPteChatBottom();
-            }
-            UpdateChatContent();
-        }
-
-        private void JumpPteChatBottom()
-        {
-            ChatManager.Instance.lockUpdate = true;
-            chatContentControl.lockType = EnhanceLockType.LockVerticalBottom;
-            chatContentControl.ResetScrollPos();
-            ResetNewInfo();
-            chatContentControl.lockType = EnhanceLockType.KeepVertical;
-        }
-
-        private void OnDisable()
-        {
-            ChatManager.OnRefreshChat -= OnRefreshChat;
-            ChatManager.OnRefreshPteChat -= OnRefreshPteChat;
-            ChatManager.OnRefreshSelf -= OnRefreshSelf;
-            ChatCenter.Instance.UpdateChatContent -= UpdateChatContent;
-            ChatManager.Instance.OnPteChatChangeEvent -= OnPteChatChangeEvent;
-            PlayerDatas.Instance.playerDataRefreshEvent -= PlayerDataRefreshInfoEvent;
-            // friendModel.RefreshFriendCntEvent -= RefreshFriendCntEvent;
-            // friendModel.RefreshFriendModel -= DisplayChatRemind;
-        }
-
-        private void RefreshFriendCntEvent(/*GroupType type, bool arg2*/)
-        {
-            // if (type == GroupType.RecentContact && m_ChatType == ChatInfoType.Friend)
-            // {
-            //     DisplayChatRemind();
-            //     if (WindowCenter.Instance.IsOpen<ChatWin>())
-            //     {
-            //         var _dict = friendModel.GetFriendInfoDict((byte)GroupType.RecentContact);
-            //         if (!_dict.ContainsKey((uint)ChatManager.Instance.PteChatID))
-            //         {
-            //             ChatManager.Instance.PteChatID = 0;
-            //         }
-            //     }
-            // }
-        }
-
-        private void PlayerDataRefreshInfoEvent(PlayerDataType refreshType)
-        {
-            if (refreshType == PlayerDataType.ExAttr10)
-            {
-                m_ChatContentControl.m_Scorller.RefreshActiveCellViews();
-            }
-        }
-    }
-
diff --git a/Main/System/Chat/ChatContentBehaviour.cs.meta b/Main/System/Chat/ChatContentBehaviour.cs.meta
deleted file mode 100644
index 9b04029..0000000
--- a/Main/System/Chat/ChatContentBehaviour.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 23701596fbb55054c8bc9a0bdc4e08f5
-MonoImporter:
-  externalObjects: {}
-  serializedVersion: 2
-  defaultReferences: []
-  executionOrder: 0
-  icon: {instanceID: 0}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 
diff --git a/Main/System/Chat/ChatData.cs b/Main/System/Chat/ChatData.cs
deleted file mode 100644
index 97018fe..0000000
--- a/Main/System/Chat/ChatData.cs
+++ /dev/null
@@ -1,220 +0,0 @@
-锘縰sing System.Text;
-using System.Collections;
-using System;
-
-public class ChatData
-{
-    public ChatData(string content)
-    {
-        _content = content;
-        if (ChatCenter.s_VoiceRegex.IsMatch(_content))
-        {
-            _content = ChatCenter.s_VoiceRegex.Replace(_content, string.Empty);
-        }
-        richText = new StringBuilder();
-        richText.Length = 0;
-        createTime = DateTime.Now;
-    }
-
-    private string _content = string.Empty;
-
-    public string content
-    {
-        get
-        {
-            if (richText.Length > 0)
-            {
-                return richText.ToString();
-            }
-            return _content;
-        }
-        protected set
-        {
-            _content = value;
-        }
-    }
-
-    public ChatInfoType type { get; protected set; }
-
-    public DateTime createTime { get; set; }
-
-    private ChatInfoType m_DetailType = ChatInfoType.World;
-    public ChatInfoType detailType
-    {
-        get
-        {
-            return m_DetailType;
-        }
-        set
-        {
-            m_DetailType = value;
-        }
-    }
-
-    public StringBuilder richText;
-
-    public ArrayList infoList = new ArrayList();
-}
-
-public class ChatUeseData : ChatData
-{
-    public ChatUeseData(string _content, int player, string name, string extra) : base(_content)
-    {
-        this.player = player;
-        this.name = name;
-        extra = UIHelper.ServerStringTrim(extra);
-        this.extra = extra;
-        this.job = 1;
-        IsSound = false;
-        var extraLength = extra.Length;
-        if (extraLength > 1)
-        {
-            vipLv = int.Parse(extra.Substring(0, 2));
-        }
-        if (extraLength > 2)
-        {
-            isGm = byte.Parse(extra.Substring(2, 1)) == 1;
-        }
-        if (extraLength > 3)
-        {
-            job = byte.Parse(extra.Substring(3, 1));
-        }
-        if (extraLength > 4)
-        {
-            bubbleId = int.Parse(extra.Substring(4, extraLength > 5 ? 2 : 1));
-        }
-        if (extraLength > 12)
-        {
-            serverGroupId = int.Parse(extra.Substring(6, 7));
-        }
-        if (extraLength > 16)
-        {
-            level = int.Parse(extra.Substring(13, 4));
-        }
-        // if (ChatCenter.s_VoiceRegex.IsMatch(_content))
-        // {
-        //     var _match = ChatCenter.s_VoiceRegex.Match(_content);
-        //     soundTick = long.Parse(_match.Groups[1].Value);
-        //     soundLength = byte.Parse(_match.Groups[2].Value)/10.0f;
-        //     IsSound = true;
-        // }
-
-        string[] parts = extra.Split('|');
-        face = (parts.Length > 4 && int.TryParse(parts[4], out var result1)) ? result1 : 0;
-        facePic = (parts.Length > 5 && int.TryParse(parts[5], out var result2)) ? result2 : 0;
-    }
-    public int player { get; protected set; }
-    public string name { get; protected set; }
-    public string extra { get; protected set; }
-    public int vipLv { get; protected set; }
-    public bool isGm { get; protected set; }
-    public int job { get; protected set; }
-    public int bubbleId { get; protected set; }
-    public long soundTick { get; private set; }
-    public bool IsSound { get; private set; }
-    public float soundLength { get; private set; }
-    public int serverGroupId { get; private set; }
-    public int level { get; private set; }
-    public int face { get; private set; }
-    public int facePic { get; private set; }
-}
-
-public class ChatSystemData : ChatData
-{
-    public ChatSystemData(string content) : base(content)
-    {
-        type = ChatInfoType.System;
-    }
-}
-
-
-// 鍠囧彮鏆傛椂涓嶈浜�
-// public class ChatTrumpetData : ChatUeseData
-// {
-//     public ChatTrumpetData(string content, int player, string name, string extra, byte speakType, string accId) : base(content, player, name, extra)
-//     {
-//         this.speakType = speakType;
-//         this.accId = accId;
-//         // type = ChatInfoType.Trumpet;
-//     }
-
-//     public byte speakType { get; protected set; }
-
-//     public string accId { get; protected set; }
-// }
-
-public class ChatWorldData : ChatUeseData
-{
-    public ChatWorldData(string content, int player, string name, string extra) : base(content, player, name, extra)
-    {
-        type = ChatInfoType.World;
-    }
-}
-
-public class ChatAreaData : ChatUeseData
-{
-    public ChatAreaData(string content, int player, string name, string extra) : base(content, player, name, extra)
-    {
-        type = ChatInfoType.Area;
-    }
-}
-
-public class ChatCrossServerData : ChatUeseData
-{
-    public ChatCrossServerData(string content, int player, string name, string extra) : base(content, player, name, extra)
-    {
-        type = ChatInfoType.CrossServer;
-    }
-}
-
-public class ChatFactionData : ChatUeseData
-{
-    public ChatFactionData(string content, int player, string name, string extra, ChatInfoType detailType = ChatInfoType.default1) : base(content, player, name, extra)
-    {
-        type = ChatInfoType.default1;
-        this.detailType = detailType;
-    }
-}
-
-public class ChatTeamData : ChatUeseData
-{
-    public ChatTeamData(string content, int player, string name, string extra, ChatInfoType detailType = ChatInfoType.Team) : base(content, player, name, extra)
-    {
-        type = ChatInfoType.Team;
-        this.detailType = detailType;
-    }
-}
-
-public class ChatFamilyData : ChatUeseData
-{
-    public ChatFamilyData(string content, int player, string name, string extra, ChatInfoType detailType = ChatInfoType.Fairy) : base(content, player, name, extra)
-    {
-        type = ChatInfoType.Fairy;
-        this.detailType = detailType;
-    }
-}
-
-public class ChatInviteData : ChatUeseData
-{
-    public ChatInviteData(string content, int player, string name, string extra) : base(content, player, name, extra)
-    {
-        type = ChatInfoType.Invite;
-    }
-}
-
-public class ChatFriendData : ChatUeseData
-{
-    public ChatFriendData(string content, int player, string name, string extra, string toName, byte talkType, uint toPlayer) : base(content, player, name, extra)
-    {
-        type = ChatInfoType.Friend;
-        this.toName = toName;
-        this.talkType = talkType;
-        this.toPlayer = (int)toPlayer;
-    }
-
-    public string toName { get; protected set; }
-
-    public byte talkType { get; protected set; }
-
-    public int toPlayer { get; protected set; }
-}
\ No newline at end of file
diff --git a/Main/System/Chat/ChatData.cs.meta b/Main/System/Chat/ChatData.cs.meta
deleted file mode 100644
index ce30f07..0000000
--- a/Main/System/Chat/ChatData.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: e982ff8b244efbc40b4832c2ed2df164
-MonoImporter:
-  externalObjects: {}
-  serializedVersion: 2
-  defaultReferences: []
-  executionOrder: 0
-  icon: {instanceID: 0}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 
diff --git a/Main/System/Chat/ChatDateCell.cs b/Main/System/Chat/ChatDateCell.cs
new file mode 100644
index 0000000..1f61063
--- /dev/null
+++ b/Main/System/Chat/ChatDateCell.cs
@@ -0,0 +1,21 @@
+锘縰sing System;
+using System.Collections;
+using UnityEngine;
+using UnityEngine.UI;
+
+public class ChatDateCell : MonoBehaviour
+{
+    [SerializeField] Text txtDate;
+    ChatManager manager { get { return ChatManager.Instance; } }
+    public void Refresh(CellView cell)
+    {
+        if (!manager.TryGetChatData(ChatManager.Instance.nowChatChannel, cell.index, out TalkData data))
+            return;
+        txtDate.text = data.Content;
+    }
+
+    public float GetHeight(string content, ArrayList list)
+    {
+        return 30;
+    }
+}
\ No newline at end of file
diff --git a/Main/System/Chat/ChatFriendTipCell.cs.meta b/Main/System/Chat/ChatDateCell.cs.meta
similarity index 83%
copy from Main/System/Chat/ChatFriendTipCell.cs.meta
copy to Main/System/Chat/ChatDateCell.cs.meta
index 2e709c7..b5da113 100644
--- a/Main/System/Chat/ChatFriendTipCell.cs.meta
+++ b/Main/System/Chat/ChatDateCell.cs.meta
@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 68376cb82e4739943aecb4dbbd81a757
+guid: f5a85178c18f4d24f99a1791bc22b0e3
 MonoImporter:
   externalObjects: {}
   serializedVersion: 2
diff --git a/Main/System/Chat/ChatExtraOneCell.cs b/Main/System/Chat/ChatExtraOneCell.cs
deleted file mode 100644
index 7bf4a9f..0000000
--- a/Main/System/Chat/ChatExtraOneCell.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-锘縰sing System.Collections;
-using System.Collections.Generic;
-using UnityEngine;
-using EnhancedUI.EnhancedScroller;
-
-    public class ChatExtraOneCell : ScrollerUI
-    {
-        [SerializeField] RichText chatText;
-
-        public override void Refresh(CellView cell)
-        {
-            ChatData _data = ChatCenter.Instance.GetChatData(ChatManager.Instance.presentChatType, cell.index);
-            if (_data == null)
-            {
-                return;
-            }
-            if (_data.infoList != null)
-            {
-                chatText.SetExtenalData(_data.infoList);
-            }
-            chatText.text = _data.content;
-            switch (_data.detailType)
-            {
-                case ChatInfoType.FairyQuestion:
-                    chatText.alignment = TextAnchor.MiddleLeft;
-                    break;
-                default:
-                    chatText.alignment = TextAnchor.MiddleCenter;
-                    break;
-            }
-        }
-    }
-
diff --git a/Main/System/Chat/ChatExtraOneCell.cs.meta b/Main/System/Chat/ChatExtraOneCell.cs.meta
deleted file mode 100644
index 7d9f006..0000000
--- a/Main/System/Chat/ChatExtraOneCell.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: b56d7af4d0244334d885f091f190b847
-MonoImporter:
-  externalObjects: {}
-  serializedVersion: 2
-  defaultReferences: []
-  executionOrder: 0
-  icon: {instanceID: 0}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 
diff --git a/Main/System/Chat/ChatFloatWin.cs b/Main/System/Chat/ChatFloatWin.cs
deleted file mode 100644
index 42d31f7..0000000
--- a/Main/System/Chat/ChatFloatWin.cs
+++ /dev/null
@@ -1,157 +0,0 @@
-锘�//--------------------------------------------------------
-//    [Author]:           鐜╀釜娓告垙
-//    [  Date ]:           Tuesday, July 24, 2018
-//--------------------------------------------------------
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using UnityEngine;
-using UnityEngine.UI;
-
-
-    public class ChatFloatWin : UIBase
-    {
-        [SerializeField] RectTransform m_ContainerFloat;
-        [SerializeField] RichText m_Chat;
-
-        DateTime overdueTime;
-
-        ChatCenter chatCenter
-        {
-            get
-            {
-                return ChatCenter.Instance;
-            }
-        }
-
-
-        protected override void OnPreOpen()
-        {
-            base.OnPreOpen();
-            m_ContainerFloat.SetActive(false);
-            ChatManager.Instance.chatFloatUpdate += ChatFloatUpdate;
-            UIManager.Instance.OnOpenWindow += OnOpenWindow;
-        }
-
-        protected override void OnOpen()
-        {
-            base.OnOpen();
-        }
-
-        protected override void OnPreClose()
-        {
-            ChatManager.Instance.chatFloatUpdate -= ChatFloatUpdate;
-            UIManager.Instance.OnOpenWindow -= OnOpenWindow;
-
-        }
-
-        protected override void OnClose()
-        {
-            base.OnClose();
-        }
-
-        protected void LateUpdate()
-        {
-            if (DateTime.Now > overdueTime && m_ContainerFloat.gameObject.activeSelf)
-            {
-                m_ContainerFloat.SetActive(false);
-            }
-        }
-
-        void OnOpenWindow(UIBase window)
-        {
-            if (window is MainWin || window is LoadingWin/* || window is TreasureBaseWin*/)
-            {
-                m_ContainerFloat.SetActive(false);
-            }
-        }
-
-        private void ChatFloatUpdate(ChatData data)
-        {
-            if (!chatCenter.IsShowChatFloat())
-            {
-                return;
-            }
-
-
-            if (data == null)
-            {
-                return;
-            }
-            if (string.IsNullOrEmpty(data.content))
-            {
-                return;
-            }
-            switch (data.type)
-            {
-                case ChatInfoType.Friend:
-                case ChatInfoType.FairyQuestion:
-                case ChatInfoType.FairyTip:
-                case ChatInfoType.TeamTip:
-                case ChatInfoType.default2:
-                    return;
-            }
-            m_ContainerFloat.SetActive(true);
-            m_Chat.text = string.Empty;
-            overdueTime = DateTime.Now.AddTicks(3 * TimeSpan.TicksPerSecond);
-            if (data.infoList != null)
-            {
-                m_Chat.SetExtenalData(data.infoList);
-            }
-            Co_SetText(StringUtility.Contact(SetChatExtraInfo(data), data.content));
-        }
-
-        void Co_SetText(string value)
-        {
-            m_Chat.text = value;
-            if (m_Chat.preferredWidth >= 1000)
-            {
-                m_Chat.alignment = TextAnchor.MiddleLeft;
-            }
-            else
-            {
-                m_Chat.alignment = TextAnchor.MiddleCenter;
-            }
-        }
-
-        string SetChatExtraInfo(ChatData data)
-        {
-            switch (data.type)
-            {
-                case ChatInfoType.World:
-                    {
-                        return string.Format("<Img chat={0}/> <color=#109d06>{1}</color>: ", "ChatIcon_World", (data as ChatUeseData).name);
-                    }
-                case ChatInfoType.Area:
-                    return string.Format("<Img chat={0}/> <color=#109d06>{1}</color>: ", "ChatIcon_Area", (data as ChatUeseData).name);
-                case ChatInfoType.CrossServer:
-                    return string.Format("<Img chat={0}/> <color=#109d06>{1}</color>: ", "ChatIcon_CrossServer", (data as ChatUeseData).name);
-                case ChatInfoType.Team:
-                    {
-                        string playerName = (data as ChatUeseData).name;
-                        return string.Format("<Img chat={0}/> <color=#109d06>{1}</color>", "ChatIcon_Team", playerName + (playerName != string.Empty ? ": " : string.Empty));
-                    }
-                case ChatInfoType.Friend:
-                    break;
-                case ChatInfoType.Fairy:
-                    {
-                        string playerName = (data as ChatUeseData).name;
-                        return string.Format("<Img chat={0}/> <color=#109d06>{1}</color>", "ChatIcon_Fairy", playerName + (playerName != string.Empty ? ": " : string.Empty));
-                    }
-                // case ChatInfoType.Trumpet:
-                //     return string.Format("<Img chat={0}/> <color=#109d06>{1}</color>: ", "ChatIcon_Trumpet", (data as ChatTrumpetData).name);
-                case ChatInfoType.Invite:
-                    return string.Format("<Img chat={0}/> ", "ChatIcon_Invite");
-                case ChatInfoType.System:
-                    return string.Format("<Img chat={0}/> ", "ChatIcon_System");
-                case ChatInfoType.default1:
-                    return string.Format("<Img chat={0}/> <color=#109d06>{1}</color>: ", "ChatIcon_default1", (data as ChatUeseData).name);
-            }
-            return string.Empty;
-        }
-    }
-
-
-
-
diff --git a/Main/System/Chat/ChatFloatWin.cs.meta b/Main/System/Chat/ChatFloatWin.cs.meta
deleted file mode 100644
index b3e634f..0000000
--- a/Main/System/Chat/ChatFloatWin.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: e77bfce9b34f5aa459bbe14732a6dab6
-MonoImporter:
-  externalObjects: {}
-  serializedVersion: 2
-  defaultReferences: []
-  executionOrder: 0
-  icon: {instanceID: 0}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 
diff --git a/Main/System/Chat/ChatFriend.cs b/Main/System/Chat/ChatFriend.cs
deleted file mode 100644
index 6d11cd5..0000000
--- a/Main/System/Chat/ChatFriend.cs
+++ /dev/null
@@ -1,147 +0,0 @@
-锘�//--------------------------------------------------------
-//    [Author]:           鐜╀釜娓告垙
-//    [  Date ]:           Wednesday, September 13, 2017
-//--------------------------------------------------------
-using UnityEngine;
-using System.Collections;
-using UnityEngine.UI;
-using System.Collections.Generic;
-using System;
-using System.Text.RegularExpressions;
-
-    public class ChatFriend : MonoBehaviour
-    {
-        [SerializeField] ScrollerController m_Controller;
-
-        private List<ChatFriendData> chatList = null;
-
-        [SerializeField] RichText destText;
-        [SerializeField] RichText destSysText;
-        private bool open = false;
-        public bool IsOpen
-        {
-            get { return open; }
-        }
-
-        private void Awake()
-        {
-            m_Controller.OnGetDynamicSize += OnGetChatDynamicSize;
-            ChatManager.Instance.SetChatFreind(this);
-        }
-
-        #region 璁$畻鍔ㄦ�佸搴﹂暱搴�
-        private bool OnGetChatDynamicSize(ScrollerDataType type, int index, out float height)
-        {
-            height = 90;
-            if (chatList == null || index >= chatList.Count)
-            {
-                return false;
-            }
-            ChatData chat = chatList[index];
-            if (type == ScrollerDataType.Extra2)
-            {
-                height = chat.content.Equals(string.Empty) ? 90 : 120;
-            }
-            else if (type == ScrollerDataType.Tail)
-            {
-                height = 30;
-            }
-            float width = 0;
-            OnGetChatDynamicHeight(chat.content, ref height, ref width, type, chat.infoList);
-            return true;
-        }
-        private void OnGetChatDynamicHeight(string content, ref float height, ref float width, ScrollerDataType type, ArrayList infoList = null)
-        {
-            if (type == ScrollerDataType.Tail)
-            {
-                destSysText.SetExtenalData(infoList);
-                destSysText.text = content;
-                width = destSysText.preferredWidth;
-                height += Mathf.Max(0, destSysText.preferredHeight - 23);
-            }
-            else
-            {
-                destText.SetExtenalData(infoList);
-                destText.text = content;
-                width = destText.preferredWidth;
-                height += Mathf.Max(0, destText.preferredHeight - 30);
-            }
-        }
-        #endregion
-
-        private void OnEnable()
-        {
-            ChatManager.OnRefreshPteChat += OnRefreshPteChat;
-            RefreshChatInfo();
-            open = true;
-            ChatManager.Instance.lockUpdate = true;
-            OnSetLock();
-        }
-
-        public void OnSetLock()
-        {
-            m_Controller.lockType = ChatManager.Instance.lockUpdate ? EnhanceLockType.LockVerticalBottom : EnhanceLockType.KeepVertical;
-            if (ChatManager.Instance.lockUpdate)
-            {
-                m_Controller.ResetScrollPos();
-            }
-        }
-
-        private void OnDisable()
-        {
-            ChatManager.OnRefreshPteChat -= OnRefreshPteChat;
-            open = false;
-        }
-
-        public void RefreshChatInfo()
-        {
-            int id = ChatManager.Instance.PteChatID;
-            chatList = ChatManager.Instance.GetChatInfo(id);
-            m_Controller.Refresh();
-            if (chatList != null)
-            {
-                for (int i = 0; i < chatList.Count; i++)
-                {
-                    if (chatList[i].soundTick != 0)
-                    {
-                        m_Controller.AddCell(ScrollerDataType.Extra2, i);
-                        continue;
-                    }
-                    if (Regex.IsMatch(chatList[i].content, ChatManager.KILL_IDENTIFY))
-                    {
-                        m_Controller.AddCell(ScrollerDataType.Tail, i);
-                        continue;
-                    }
-                    if (chatList[i].player == PlayerDatas.Instance.baseData.PlayerID)
-                    {
-                        m_Controller.AddCell(ScrollerDataType.Header, i);
-                    }
-                    else
-                    {
-                        m_Controller.AddCell(ScrollerDataType.Normal, i);
-                    }
-                }
-            }
-            m_Controller.Restart();
-        }
-
-        private void OnRefreshPteChat(ChatFriendData data)
-        {
-            if (data == null)
-            {
-                return;
-            }
-            if (data.toPlayer != ChatManager.Instance.PteChatID && data.player != ChatManager.Instance.PteChatID)
-            {
-                return;
-            }
-            if (data.player == PlayerDatas.Instance.baseData.PlayerID)
-            {
-
-            }
-            RefreshChatInfo();
-        }
-    }
-
-
-
diff --git a/Main/System/Chat/ChatFriend.cs.meta b/Main/System/Chat/ChatFriend.cs.meta
deleted file mode 100644
index a95b1ec..0000000
--- a/Main/System/Chat/ChatFriend.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 3056ddc13bd52ed4483c16475a2fcc08
-MonoImporter:
-  externalObjects: {}
-  serializedVersion: 2
-  defaultReferences: []
-  executionOrder: 0
-  icon: {instanceID: 0}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 
diff --git a/Main/System/Chat/ChatFriendCell.cs b/Main/System/Chat/ChatFriendCell.cs
deleted file mode 100644
index 5d0432f..0000000
--- a/Main/System/Chat/ChatFriendCell.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-锘縰sing System.Collections;
-using System.Collections.Generic;
-using UnityEngine;
-using UnityEngine.UI;
-
-//public class ChatFriendCell : ScrollerUI
-//{
-//    [SerializeField] RichText m_ChatText;
-//    [SerializeField] Text m_VipText;
-//    [SerializeField] Text m_NameText;
-//    [SerializeField] AvatarCell m_ChatIcon;
-//    [SerializeField] ImageFitterText m_ImageFitter;
-
-//    public override void Refresh(CellView cell)
-//    {
-//        var _index = cell.index;
-//        int _playerId = ChatCtrl.Inst.PteChatID;
-//        var _list = ChatCtrl.Inst.GetChatInfo(_playerId);
-//        if (_list != null && _index < _list.Count)
-//        {
-//            ChatFriendData chat = _list[_index];
-//            m_ChatText.text = chat.content;
-//            if (type == ScrollerDataType.Header)
-//            {
-//                m_ChatText.AutoNewLine = false;
-//                if (m_ChatText.preferredWidth > m_ChatText.rectTransform.rect.width)
-//                {
-//                    m_ChatText.alignment = TextAnchor.UpperLeft;
-//                }
-//                else
-//                {
-//                    m_ChatText.alignment = TextAnchor.UpperRight;
-//                }
-//                m_ChatText.AutoNewLine = true;
-//            }
-//            m_ImageFitter.FiterRealTxtWidth = m_ChatText.alignment == TextAnchor.UpperRight;
-//            m_VipText.text = chat.vipLv > 0 ? StringUtility.Contact("V", chat.vipLv) : string.Empty;
-//            m_NameText.text = chat.name;
-//            m_ChatIcon.InitUI(AvatarHelper.GetAvatarModel(chat.player, chat.face, chat.facePic, chat.job));
-//            m_ChatText.text = chat.content;
-//        }
-//    }
-//}
-
diff --git a/Main/System/Chat/ChatFriendCell.cs.meta b/Main/System/Chat/ChatFriendCell.cs.meta
deleted file mode 100644
index cf8cd67..0000000
--- a/Main/System/Chat/ChatFriendCell.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 3c7103d0f86bb6c4fb02025e35939eb3
-MonoImporter:
-  externalObjects: {}
-  serializedVersion: 2
-  defaultReferences: []
-  executionOrder: 0
-  icon: {instanceID: 0}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 
diff --git a/Main/System/Chat/ChatFriendTipCell.cs b/Main/System/Chat/ChatFriendTipCell.cs
deleted file mode 100644
index 95ca949..0000000
--- a/Main/System/Chat/ChatFriendTipCell.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-锘縰sing System.Collections;
-using System.Collections.Generic;
-using UnityEngine;
-namespace EnhancedUI.EnhancedScroller
-{
-    // public class ChatFriendTipCell : ScrollerUI
-    // {
-    //     [SerializeField] RichText m_TipText;
-    //     public override void Refresh(CellView cell)
-    //     {
-    //         var _index = cell.index;
-    //         int _playerId = ChatCtrl.Inst.PteChatID;
-    //         var _list = ChatCtrl.Inst.GetChatInfo(_playerId);
-    //         if (_list != null && _index < _list.Count)
-    //         {
-    //             ChatFriendData chat = _list[_index];
-    //             m_TipText.text = chat.content.Replace(ChatCtrl.KILL_IDENTIFY, string.Empty);
-    //         }
-    //     }
-    // }
-}
-
diff --git a/Main/System/Chat/ChatItemCell.cs b/Main/System/Chat/ChatItemCell.cs
deleted file mode 100644
index 99ca228..0000000
--- a/Main/System/Chat/ChatItemCell.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-锘縰sing System.Collections;
-using System.Collections.Generic;
-using UnityEngine;
-using UnityEngine.UI;
-
-public class ChatItemCell : CellView
-{
-    [SerializeField] List<ItemCell> m_Items;
-    public List<ItemCell> items { get { return m_Items; } }
-    [SerializeField] List<Image> m_ItemEquips;
-    public List<Image> itemEquips { get { return m_ItemEquips; } }
-}
-
diff --git a/Main/System/Chat/ChatItemCell.cs.meta b/Main/System/Chat/ChatItemCell.cs.meta
deleted file mode 100644
index 880a2ad..0000000
--- a/Main/System/Chat/ChatItemCell.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 54be5c5a694cce842a5ad0dc6e7bbe76
-MonoImporter:
-  externalObjects: {}
-  serializedVersion: 2
-  defaultReferences: []
-  executionOrder: 0
-  icon: {instanceID: 0}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 
diff --git a/Main/System/Chat/ChatManager.cs b/Main/System/Chat/ChatManager.cs
index e557ce9..0691b0c 100644
--- a/Main/System/Chat/ChatManager.cs
+++ b/Main/System/Chat/ChatManager.cs
@@ -3,1447 +3,660 @@
 using UnityEngine;
 using System.Text;
 using System;
-using System.Text.RegularExpressions;
+using LitJson;
 
-using System.Linq;
-
-public class ChatManager : GameSystemManager<ChatManager>
+public partial class ChatManager : GameSystemManager<ChatManager>
 {
-    public int CHAT_INFO_CNT = 50;
+    public ChatChannel nowChatChannel;
 
-    public const int CHAT_TIP_CNT = 4;
-    public const int CHAT_CELL_CNT = 6;
-    public const int CHAT_INFO_LIMIT = 50;
+    //<ChannelType,TalkData>
+    public Dictionary<ChatChannel, List<TalkData>> talkDict = new Dictionary<ChatChannel, List<TalkData>>();
+    public Dictionary<int, ChatBubbleData> chatBubbles = new Dictionary<int, ChatBubbleData>();
+    //<ChannelType,鏃堕棿鎴�>
+    public Dictionary<int, int> chatChannelSendTime = new Dictionary<int, int>();
+    public event Action<ChatChannel, TalkData> OnUpdateTalkEvent;
+    public event Action OnUpdateTalkCacheListEvent;
 
-    public readonly int BugleItem = 0;//鍠囧彮鐗╁搧id
+    public Dictionary<int, int> chatChannelCD = new Dictionary<int, int>();
+    public int[] areaMyColorArr;
+    public Color32 areaMyColor;
+    public int[] areaOtherColorArr;
+    public Color32 areaOtherColor;
+    public Dictionary<int, int[]> chatChannelBulletColorArrDict = new Dictionary<int, int[]>();
+    public Dictionary<ChatChannel, Color32> chatChannelBulletColorDict = new Dictionary<ChatChannel, Color32>();
 
-    static StringBuilder sb = new StringBuilder();
-    /// <summary>
-    /// 鑱婂ぉ淇℃伅
-    /// </summary>
-    private bool _lockUpdate = true;
-    public bool lockUpdate {
-        get {
-            return _lockUpdate;
-        }
-        set {
-            _lockUpdate = value;
-            if (ChatFriend != null && ChatFriend.IsOpen)
-            {
-                ChatFriend.OnSetLock();
-            }
-        }
-    }
+    public int[] defaultChannelBulletColorArr;
+    public Color32 defaultChannelBulletColor;
+    public int characterLimit;
+    public int sysBubbleID;
+    public int[] sysBubbleColorArr;
+    public Color32 sysBubbleColor;
 
-    private Dictionary<ChatInfoType, List<ChatData>> chatDics = new Dictionary<ChatInfoType, List<ChatData>>();
 
-    private Dictionary<ChatInfoType, bool> chatOpenDics = new Dictionary<ChatInfoType, bool>();
-
-    public List<ChatData> chatDisplayList = new List<ChatData>();
-
-    #region 绉佽亰
-    private Dictionary<int, List<ChatFriendData>> pteChatDics = new Dictionary<int, List<ChatFriendData>>();
-    public event Action OnPteChatChangeEvent;
-    public event Action<int> SelectRecentlyEvent;
-    public static event OnChatPteRefresh OnRefreshPteChat;
-    private int pteChatId = 0;
-    public int PteChatID {
-        get { return pteChatId; }
-        set {
-            if (pteChatId == value)
-            {
-                return;
-            }
-            pteChatId = value;
-            if (OnPteChatChangeEvent != null)
-            {
-                OnPteChatChangeEvent();
-            }
-            if (ChatFriend != null && ChatFriend.IsOpen)
-            {
-                ChatFriend.RefreshChatInfo();
-            }
-        }
-    }
-    private string pteChatName = string.Empty;
-    public string PteChatName {
-        get { return pteChatName; }
-        set { pteChatName = value; }
-    }
-
-    private ChatFriend m_ChatFriend;
-    public ChatFriend ChatFriend {
-        get { return m_ChatFriend; }
-    }
-
-    public void ClearPteChat(int playerId)
+    public override void Init()
     {
-        var id = (int)PlayerDatas.Instance.PlayerId + playerId;
-        if (pteChatDics.ContainsKey(id))
+        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent += OnBeforePlayerDataInitializeEvent;
+        DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent += OnPlayerLoginOk;
+        GuildManager.Instance.EnterOrQuitGuildEvent += EnterOrQuitGuildEvent;
+
+        var config = FuncConfigConfig.Get("TalkCD");
+        chatChannelCD = ConfigParse.ParseIntDict(config.Numerical1);
+
+        config = FuncConfigConfig.Get("TalkColor");
+        areaMyColorArr = ConfigParse.GetMultipleStr<int>(config.Numerical1);
+        areaMyColor = new Color32()
         {
-            pteChatDics.Remove(id);
-            if (OnRefreshPteChat != null)
+            r = (byte)(areaMyColorArr.Length > 0 ? areaMyColorArr[0] : 0),
+            g = (byte)(areaMyColorArr.Length > 1 ? areaMyColorArr[1] : 0),
+            b = (byte)(areaMyColorArr.Length > 2 ? areaMyColorArr[2] : 0),
+            a = (byte)(areaMyColorArr.Length > 3 ? areaMyColorArr[3] : 255),
+        };
+
+        areaOtherColorArr = ConfigParse.GetMultipleStr<int>(config.Numerical2);
+        areaOtherColor = new Color32()
+        {
+            r = (byte)(areaOtherColorArr.Length > 0 ? areaOtherColorArr[0] : 0),
+            g = (byte)(areaOtherColorArr.Length > 1 ? areaOtherColorArr[1] : 0),
+            b = (byte)(areaOtherColorArr.Length > 2 ? areaOtherColorArr[2] : 0),
+            a = (byte)(areaOtherColorArr.Length > 3 ? areaOtherColorArr[3] : 255),
+        };
+
+        chatChannelBulletColorArrDict = ConfigParse.ParseIntArrayDict(config.Numerical3);
+        foreach (var kv in chatChannelBulletColorArrDict)
+        {
+            if (!IsValidChatChannel(kv.Key))
+                continue;
+            chatChannelBulletColorDict[(ChatChannel)kv.Key] = new Color32()
             {
-                OnRefreshPteChat(null);
-            }
+                r = (byte)(kv.Value.Length > 0 ? kv.Value[0] : 0),
+                g = (byte)(kv.Value.Length > 1 ? kv.Value[1] : 0),
+                b = (byte)(kv.Value.Length > 2 ? kv.Value[2] : 0),
+                a = (byte)(kv.Value.Length > 3 ? kv.Value[3] : 0),
+            };
+        }
+
+        defaultChannelBulletColorArr = ConfigParse.GetMultipleStr<int>(config.Numerical4);
+        defaultChannelBulletColor = new Color32()
+        {
+            r = (byte)(defaultChannelBulletColorArr.Length > 0 ? defaultChannelBulletColorArr[0] : 0),
+            g = (byte)(defaultChannelBulletColorArr.Length > 1 ? defaultChannelBulletColorArr[1] : 0),
+            b = (byte)(defaultChannelBulletColorArr.Length > 2 ? defaultChannelBulletColorArr[2] : 0),
+            a = (byte)(defaultChannelBulletColorArr.Length > 3 ? defaultChannelBulletColorArr[3] : 255),
+        };
+
+        config = FuncConfigConfig.Get("TalkLimit");
+        characterLimit = int.Parse(config.Numerical1);
+
+        config = FuncConfigConfig.Get("TalkBubble");
+        sysBubbleID = int.Parse(config.Numerical1);
+        sysBubbleColorArr = ConfigParse.GetMultipleStr<int>(config.Numerical2);
+        sysBubbleColor = new Color32()
+        {
+            r = (byte)(sysBubbleColorArr.Length > 0 ? sysBubbleColorArr[0] : 0),
+            g = (byte)(sysBubbleColorArr.Length > 1 ? sysBubbleColorArr[1] : 0),
+            b = (byte)(sysBubbleColorArr.Length > 2 ? sysBubbleColorArr[2] : 0),
+            a = (byte)(sysBubbleColorArr.Length > 3 ? sysBubbleColorArr[3] : 255),
+        };
+    }
+
+    public override void Release()
+    {
+        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent -= OnBeforePlayerDataInitializeEvent;
+        DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent -= OnPlayerLoginOk;
+        GuildManager.Instance.EnterOrQuitGuildEvent -= EnterOrQuitGuildEvent;
+    }
+
+    //琚涪鍑�/閫�鍑哄伐浼氭椂锛屽垏鎹㈣亰澶╅閬�
+    private void EnterOrQuitGuildEvent(bool obj)
+    {
+        if (!obj)
+        {
+            nowChatChannel = ChatChannel.World;
+            nowChatTab = ChatTab.World;
         }
     }
 
-    public void SelectRecentlyChat(int playerId)
+    private void OnBeforePlayerDataInitializeEvent()
     {
-        if (SelectRecentlyEvent != null)
-        {
-            SelectRecentlyEvent(playerId);
-        }
-    }
-    #endregion
-
-    private List<ChatData> chatlist = new List<ChatData>();
-    private List<ChatData> chatUpList = new List<ChatData>();
-
-    public delegate void OnChatRefresh(ChatInfoType type);
-    public static event OnChatRefresh OnRefreshChat;
-
-    public delegate void OnChatSelfRefresh(ChatData data);
-    public static event OnChatSelfRefresh OnRefreshSelf;
-
-    public delegate void OnChatPteRefresh(ChatFriendData data);
-
-    public ChatInfoType presentChatType {
-        get; set;
+        talkDict.Clear();
+        ParseChatBubbleConfig();
+        nowChatChannel = ChatChannel.World;
+        nowChatTab = ChatTab.World;
     }
 
-    public event Action OnClickCloseChatEvent;
-    public event Action<bool> OnChatExtentOpenEvent;
-
-    public event Action<ChatData> chatFloatUpdate;
-
-    // TeamModel teamModel {
-    //     get {
-    //         return ModelCenter.Instance.GetModel<TeamModel>();
-    //     }
-    // }
-
-    // FriendsModel friendModel {
-    //     get { return ModelCenter.Instance.GetModel<FriendsModel>(); }
-    // }
-
-    // EquipGemModel equipGemModel { get { return ModelCenter.Instance.GetModel<EquipGemModel>(); } }
-    // EquipStrengthModel equipStrengthModel { get { return ModelCenter.Instance.GetModel<EquipStrengthModel>(); } }
-    // EquipStarModel equipStarModel { get { return ModelCenter.Instance.GetModel<EquipStarModel>(); } }
-    // EquipTrainModel equipTrainModel { get { return ModelCenter.Instance.GetModel<EquipTrainModel>(); } }
-    // EquipModel equipModel { get { return ModelCenter.Instance.GetModel<EquipModel>(); } }
-    PackManager packManager => PackManager.Instance;
-    // DungeonAssistModel dungeonAssistModel { get { return ModelCenter.Instance.GetModel<DungeonAssistModel>(); } }
-
-    public Dictionary<ChatInfoType, List<string>> achievementRandoms = new Dictionary<ChatInfoType, List<string>>();
-    List<string> assistThankLanguages = new List<string>();
-    Int2 assistThankLevelLimit = new Int2(150, 200);
-
-    public ChatManager()
+    private void OnPlayerLoginOk()
     {
-        chatOpenDics.Add(ChatInfoType.System, true);
-        chatOpenDics.Add(ChatInfoType.World, true);
-        chatOpenDics.Add(ChatInfoType.CrossServer, true);
-        chatOpenDics.Add(ChatInfoType.Area, true);
-        chatOpenDics.Add(ChatInfoType.Team, true);
-        chatOpenDics.Add(ChatInfoType.Invite, true);
-        chatOpenDics.Add(ChatInfoType.Trumpet, true);
-        chatOpenDics.Add(ChatInfoType.Fairy, true);
-        chatOpenDics.Add(ChatInfoType.default1, true);
-        lockUpdate = true;
-        presentChatType = ChatInfoType.World;
-        IsExtentOpen = false;
-
-        // var _funcCfg = FuncConfigConfig.Get("BugleItem");
-        // BugleItem = int.Parse(_funcCfg.Numerical1);
-
-        DTC0102_tagCDBPlayer.switchAccountEvent += SwitchAccountEvent;
-        // TODO YYL
-        // StageLoad.Instance.onStageLoadFinish += OnStageLoadFinish;
-        DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent += PlayerLoginOkEvent;
-
-        InitChatRedpoints();
-
-        // FuncConfigConfig _cfg = FuncConfigConfig.Get("RandomWord");
-        // try
-        // {
-        //     achievementRandoms.Add(ChatInfoType.World, new List<string>(ConfigParse.GetMultipleStr(_cfg.Numerical1)));
-        //     achievementRandoms.Add(ChatInfoType.Fairy, new List<string>(ConfigParse.GetMultipleStr(_cfg.Numerical2)));
-        //     var json = LitJson.JsonMapper.ToObject(_cfg.Numerical3);
-        //     foreach (var key in json.Keys)
-        //     {
-        //         var type = int.Parse(key);
-        //         m_TaskRandomChats.Add(type, new List<string>(LitJson.JsonMapper.ToObject<string[]>(json[key].ToJson())));
-        //     }
-        //     assistThankLanguages.AddRange(ConfigParse.GetMultipleStr(_cfg.Numerical4));
-        //     if (!string.IsNullOrEmpty(_cfg.Numerical5))
-        //     {
-        //         var levelArray = ConfigParse.GetMultipleStr<int>(_cfg.Numerical5);
-        //         assistThankLevelLimit = new Int2(levelArray[0], levelArray[1]);
-        //     }
-        // }
-        // catch (Exception e)
-        // {
-        //     Debug.LogError(e.Message);
-        // }
+        LoadBulletSettings();
     }
 
-    private void PlayerLoginOkEvent()
+    public void AddChatChannelSendTime(ChatChannel chatChannel, int time)
     {
-        UpdateRedpoint(ChatInfoType.Team);
-        UpdateRedpoint(ChatInfoType.Fairy);
+        chatChannelSendTime[(int)chatChannel] = time;
     }
 
-    private void SwitchAccountEvent()
+    public bool TryGetChatChannelSendTime(ChatChannel chatChannel, out int time)
     {
-        ClearAllChatInfo();
+        return chatChannelSendTime.TryGetValue((int)chatChannel, out time);
     }
 
-    void ChatReport(ChatInfoType chatType, string content, string toPlayer)
+    public bool TryGetChatChannelSendCD(ChatChannel chatChannel, out int cd)
     {
-        try
-        {
-            if (ChatCenter.Instance.IsChatBanned || ChatCenter.Instance.IsClientBan(chatType) ||
-                IsInviteChat(content) || KillRegex.IsMatch(content))
-            {
-                return;
-            }
-            var channelName = string.Empty;
-            switch (chatType)
-            {
-                case ChatInfoType.World:
-                    channelName = Language.Get("ChatType_World");
-                    break;
-                case ChatInfoType.Area:
-                    channelName = Language.Get("ChatType_Area");
-                    break;
-                case ChatInfoType.CrossServer:
-                    channelName = Language.Get("ChatType_CrossServer");
-                    break;
-                case ChatInfoType.Team:
-                    channelName = Language.Get("ChatType_Team");
-                    break;
-                case ChatInfoType.Invite:
-                    channelName = Language.Get("ChatType_Invite");
-                    break;
-                case ChatInfoType.Trumpet:
-                    channelName = Language.Get("ChatType_Trumpet");
-                    break;
-                case ChatInfoType.Fairy:
-                    channelName = Language.Get("ChatType_Fairy");
-                    break;
-                case ChatInfoType.Friend:
-                    channelName = Language.Get("PlayerDetail_PrivateChat");
-                    break;
-                case ChatInfoType.default1:
-                    channelName = Language.Get("ChatType_default1");
-                    break;
-                default:
-                    return;
-            }
-            // TODO YYL
-            // OperationLogCollect.Instance.ChatReport(content, channelName, chatType == ChatInfoType.Friend ? toPlayer : string.Empty, chatType);
-        }
-        catch (Exception e)
-        {
-            Debug.Log(e.StackTrace + e.Message);
-        }
+        return chatChannelCD.TryGetValue((int)chatChannel, out cd);
     }
 
-    public void SendChatInfo(ChatInfoType type, string msg, ChatExtraData? info = null , bool isDirtyWord = true,  bool isChatInfoCount = true)
+    public bool IsCanSend(ChatChannel chatChannel, out int remainingSeconds)
     {
-        bool isDirty = false;
-        bool isVoice = ChatCenter.s_VoiceRegex.IsMatch(msg);
-
-        if (CheckEmptyChat(msg))
-        {
-            SysNotifyMgr.Instance.ShowTip("CanootTalk14");
-            return;
-        }
-
-        ChatReport(type, msg, PteChatName);
-
-        if (!isVoice && !InviteRegex.IsMatch(msg))
-        {
-            if (isDirtyWord)
-            {
-                isDirty = DirtyWordConfig.IsDirtWord(msg);
-                if (isDirty)
-                    msg = DirtyWordConfig.IsDirtWord(msg, '*');
-            }
-
-            var length = GetChatMessageLength(msg);
-            if (isChatInfoCount)
-            {
-                if (length > CHAT_INFO_CNT)
-                {
-                    ServerTipDetails.DisplayNormalTip(Language.Get("L1014"));
-                    return;
-                }
-            }
-
-            if (itemPlaceList.Count > 5)
-            {
-                SysNotifyMgr.Instance.ShowTip("ChatSendItemLimit");
-                return;
-            }
-        }
-        LanguageVerify.toPlayer = (uint)PteChatID;
-        LanguageVerify.toPlayerName = PteChatName;
-        LanguageVerify.Instance.VerifyChat(msg, type, (bool ok, string result) =>
-         {
-             if (ok)
-             {
-                 ChatCenter.RecentlyChat _recentlyChat = null;
-                 if (!isDirty && !isVoice)
-                 {
-                     _recentlyChat = ChatCenter.Instance.SaveRecentlyChat(result);
-                 }
-                 msg = CheckHasItem(result, _recentlyChat);
-                 ChatCenter.Instance.recentlyChat = null;
-
-                 if (ChatCenter.Instance.IsChatBanned || ChatCenter.Instance.IsClientBan(type))
-                 {
-                     var toPlayer = PteChatID;
-                     if (info.HasValue && info.Value.infoint1 == 0)
-                     {
-                         toPlayer = info.Value.infoint1;
-                     }
-                     ChatCenter.Instance.HandleChatBanned(type, msg, toPlayer);
-                     return;
-                 }
-
-                 switch (type)
-                 {
-                     case ChatInfoType.World:
-                     case ChatInfoType.Fairy:
-                         if (IsAssitChat(msg) != 0)
-                         {
-                            //  TODO YYL
-                            // teamModel.RequestAssistAutoMatch();
-                         }
-                         break;
-                 }
-
-                 switch (type)
-                 {
-                     case ChatInfoType.World:
-                         {
-                             C0201_tagCTalkGong chatPack = new C0201_tagCTalkGong();
-                             chatPack.Len = (ushort)GetUTF8InfoLen(msg);
-                             chatPack.Content = msg;
-                             GameNetSystem.Instance.SendInfo(chatPack);
-                         }
-                         break;
-                     case ChatInfoType.Area:
-                         {
-                             C0207_tagCTalkArea chatPack = new C0207_tagCTalkArea();
-                             chatPack.Len = (ushort)GetUTF8InfoLen(msg);
-                             chatPack.Content = msg;
-                             GameNetSystem.Instance.SendInfo(chatPack); 
-                         }
-                         break;
-                     case ChatInfoType.CrossServer:
-                         {
-                             C0208_tagCTalkCountry chatPack = new C0208_tagCTalkCountry();
-                             chatPack.Len = (ushort)GetUTF8InfoLen(msg);
-                             chatPack.Content = msg;
-                             GameNetSystem.Instance.SendInfo(chatPack);
-                         }
-                         break;
-                     case ChatInfoType.Team:
-                         {
-                             C0205_tagCTalkDui chatPack = new C0205_tagCTalkDui();
-                             chatPack.Len = (ushort)GetUTF8InfoLen(msg);
-                             chatPack.Content = msg;
-                             GameNetSystem.Instance.SendInfo(chatPack);
-                         }
-                         break;
-                     case ChatInfoType.Friend:
-                         {
-                             var _toPlayer = PteChatID;
-                             if (info.HasValue && info.Value.infoint1 == 0)
-                             {
-                                 _toPlayer = info.Value.infoint1;
-                             }
-                             if (_toPlayer == 0)
-                             {
-                                 SysNotifyMgr.Instance.ShowTip("NoChatTarget");
-                                 return;
-                             }
-                             SendFriendChat(msg, _toPlayer);
-                         }
-                         break;
-                     case ChatInfoType.Fairy:
-                         {
-                             C0203_tagCTalkBang chatPack = new C0203_tagCTalkBang();
-                             chatPack.Len = (ushort)GetUTF8InfoLen(msg);
-                             chatPack.Content = msg;
-                             GameNetSystem.Instance.SendInfo(chatPack);
-                         }
-                         break;
-                     case ChatInfoType.Trumpet:
-                         {
-                             if (info.HasValue)
-                             {
-                                 CA217_tagCMPYSpeaker _pak = new CA217_tagCMPYSpeaker();
-                                 _pak.SpeakerType = 1;
-                                 _pak.IsUseGold = 0;
-                                 _pak.ItemIndex = (byte)info.Value.infoint1;
-                                 _pak.TextLen = (ushort)GetUTF8InfoLen(msg);
-                                 _pak.Text = msg;
-                                 GameNetSystem.Instance.SendInfo(_pak);
-                             }
-                         }
-                         break;
-                     case ChatInfoType.default1:
-                         {
-                             if (PlayerDatas.Instance.baseData.faction == 0)
-                             {
-                                 SysNotifyMgr.Instance.ShowTip("FactionChatLimit");
-                                 return;
-                             }
-                             CA216_tagCMPyTalk _pak = new CA216_tagCMPyTalk();
-                             _pak.TalkType = 100;
-                             _pak.Len = (ushort)GetUTF8InfoLen(msg);
-                             _pak.Content = msg;
-                             GameNetSystem.Instance.SendInfo(_pak);
-                         }
-                         break;
-                 }
-             }
-         });
-    }
-
-    int GetChatMessageLength(string message)
-    {
-        message = WordAnalysis.Color_Start_Regex.Replace(message, string.Empty);
-        message = WordAnalysis.Color_End_Regex.Replace(message, string.Empty);
-        return message.Length;
-    }
-
-    bool CheckEmptyChat(string msg)
-    {
-        if (string.IsNullOrEmpty(msg.Replace(" ", string.Empty)))
-        {
+        remainingSeconds = 0;
+        // 娌℃湁閰嶇疆鐨勪笉闄愬埗
+        if (!TryGetChatChannelSendCD(chatChannel, out int cd))
             return true;
-        }
+        // 娌℃湁鍙戦�佽繃 
+        if (!TryGetChatChannelSendTime(chatChannel, out int time) || time <= 0)
+            return true;
+        DateTime endDateTime = TimeUtility.GetTime((uint)(cd + time + 1));
+        TimeSpan remainingTime = endDateTime - TimeUtility.ServerNow;
+        remainingSeconds = (int)remainingTime.TotalSeconds;
+        if (remainingSeconds <= 0)
+            return true;
         return false;
     }
-    /// <summary>
-    /// 涓栫晫棰戦亾
-    /// </summary>
-    /// <param name="vNetData"></param>
-    public void RevChatInfo(H0201_tagTalkGong vNetData, uint time = 0)
+    // 0-绯荤粺 1-鏃ユ湡 2-鑷繁 3-鍏朵粬鐜╁
+    public int GetTalkDataType(TalkData talkData)
     {
-        //  TODO YYL
-        // if (friendModel.GetFirendInfo(vNetData.PlayerID, (byte)GroupType.Balcklist) != null)//榛戝悕鍗曟嫤鎴�
-        // {
-        //     return;
-        // }
-        ChatData chatData = null;
-        var content = vNetData.Content;
-        if (IsInviteChat(vNetData.Content))
+        if (talkData.isSystem)
         {
-            content = InviteRegex.Replace(vNetData.Content, "");
-
-            // if (teamModel.myTeam.GetIndexOfMember((int)vNetData.PlayerID) != -1)
-            // {
-            //     content = StringUtility.Contact("<color=#f8983b>", vNetData.Name, "</color>", "锛�", content);
-            // }
-            // else
-            {
-                content = StringUtility.Contact("<color=#f8983b>", vNetData.Name, "</color>", "锛�", content, string.Format("<color=#00ff00><a>{0}|invite={1}</a></color>", Language.Get("L1013"), vNetData.PlayerID));
-            }
-            chatData = new ChatInviteData(content, (int)vNetData.PlayerID, vNetData.Name, vNetData.Extras);
-            KeepChatInfo(chatData);
-            return;
+            return 0;
         }
-        if (IsAssitChat(content, true) == 2 && vNetData.PlayerID != PlayerDatas.Instance.baseData.PlayerID)
+        else if (talkData.isDate)
         {
-            content = StringUtility.Contact(content, Language.Get("InviteTeam", vNetData.PlayerID));
+            return 1;
         }
-        chatData = new ChatWorldData(content, (int)vNetData.PlayerID, vNetData.Name, vNetData.Extras);
-        if (time != 0)
+        else if (talkData.PlayerID == PlayerDatas.Instance.PlayerId)
         {
-            chatData.createTime = TimeUtility.GetTime(time);
-        }
-        LocalChatHistory.Save(chatData as ChatUeseData);
-        KeepChatInfo(chatData);
-    }
-    /// <summary>
-    /// 鍖哄煙棰戦亾
-    /// </summary>
-    /// <param name="vNetData"></param>
-    public void RevChatInfo(H0207_tagTalkArea vNetData)
-    {
-        //  TODO YYL
-        // if (friendModel.GetFirendInfo(vNetData.PlayerID, (byte)GroupType.Balcklist) != null)//榛戝悕鍗曟嫤鎴�
-        // {
-        //     return;
-        // }
-        ChatData chatData = new ChatAreaData(vNetData.Content, (int)vNetData.PlayerID, vNetData.SrcName, vNetData.Extras);
-        LocalChatHistory.Save(chatData as ChatUeseData);
-        KeepChatInfo(chatData);
-    }
-
-    // 闃佃惀棰戦亾
-    public void RevChatInfo(HA707_tagMCPyTalk vNetData)
-    {
-        //  TODO YYL
-        // if (friendModel.GetFirendInfo(vNetData.PlayerID, (byte)GroupType.Balcklist) != null)//榛戝悕鍗曟嫤鎴�
-        // {
-        //     return;
-        // }
-        ChatData chatData = new ChatFactionData(vNetData.Content, (int)vNetData.PlayerID, vNetData.Name, vNetData.Extras);
-        LocalChatHistory.Save(chatData as ChatUeseData);
-        KeepChatInfo(chatData);
-    }
-
-    /// <summary>
-    /// 璺ㄦ湇鑱婂ぉ
-    /// </summary>
-    /// <param name="package"></param>
-    public void RevChatInfo(H0208_tagTalkCountry package)
-    {
-        //  TODO YYL
-        // if (friendModel.GetFirendInfo(package.PlayerID, (byte)GroupType.Balcklist) != null)//榛戝悕鍗曟嫤鎴�
-        // {
-        //     return;
-        // }
-        if (!FuncOpen.Instance.IsFuncOpen(162))
-        {
-            return;
-        }
-        ChatData chatData = new ChatCrossServerData(package.Content, (int)package.PlayerID, package.Name, package.Extras);
-        LocalChatHistory.Save(chatData as ChatUeseData);
-        KeepChatInfo(chatData);
-    }
-
-    /// <summary>
-    /// 鍠囧彮鍠婅瘽
-    /// </summary>
-    /// <param name="vNetData"></param>
-    public void RevChatInfo(HA9A3_tagGCPYSpeakerContent vNetData)
-    {
-        // ChatData chatData = new ChatTrumpetData(vNetData.Text, (int)vNetData.PlayerID, vNetData.Name, vNetData.Extras, vNetData.SpeakerType, vNetData.AccID);
-        // LocalChatHistory.Save(chatData as ChatUeseData);
-        // KeepChatInfo(chatData);
-        // ServerTipDetails.ShowTrumpetTip(chatData as ChatTrumpetData);
-    }
-    /// <summary>
-    /// 瀹舵棌棰戦亾
-    /// </summary>
-    /// <param name="vNetData"></param>
-    public void RevChatInfo(H0203_tagTalkBang vNetData, uint time = 0)
-    {
-        var content = vNetData.Content;
-        if (IsAssitChat(content, true) == 1 && vNetData.PlayerID != PlayerDatas.Instance.baseData.PlayerID)
-        {
-            content = StringUtility.Contact(content, Language.Get("InviteTeam", vNetData.PlayerID));
-        }
-        ChatData chatData = new ChatFamilyData(content, (int)vNetData.PlayerID, vNetData.Name, vNetData.Extras);
-        if (time != 0)
-        {
-            chatData.createTime = TimeUtility.GetTime(time);
-        }
-        LocalChatHistory.Save(chatData as ChatUeseData);
-        KeepChatInfo(chatData);
-        ReceiveNewChat(ChatInfoType.Fairy);
-    }
-
-    /// <summary>
-    /// 鍚庣缂撳瓨
-    /// </summary>
-    /// <param name="vNetData"></param>
-    public void RevChatInfo(HB311_tagGCTalkCache package)
-    {
-        for (int i = 0; i < package.Count; i++)
-        {
-            var data = package.InfoList[i];
-            if (data.ChannelType == 1)
-            {
-                RevChatInfo(new H0201_tagTalkGong()
-                {
-                    socketType = package.socketType,
-                    Content = data.Content,
-                    Extras = data.Extras,
-                    ExtraValue = 0,
-                    Name = data.Name,
-                    NameLen = data.NameLen,
-                    Len = data.Len,
-                    PlayerID = data.PlayerID,
-                }, data.Time);
-            }
-            else if (data.ChannelType == 2)
-            {
-                RevChatInfo(new H0203_tagTalkBang()
-                {
-                    socketType = package.socketType,
-                    Content = data.Content,
-                    Extras = data.Extras,
-                    ExtraValue = 0,
-                    Len = data.Len,
-                    Name = data.Name,
-                    NameLen = data.NameLen,
-                    PlayerID = data.PlayerID,
-                });
-            }
-        }
-    }
-
-    /// <summary>
-    /// 濂藉弸绉佽亰
-    /// </summary>
-    /// <param name="vNetData"></param>
-    public void SetChatFreind(ChatFriend inst)
-    {
-        m_ChatFriend = inst;
-    }
-    public void RevChatInfo(H0206_tagTalkMi vNetData)
-    {
-        if (Regex.IsMatch(vNetData.Content, KILL_IDENTIFY))
-        {
-            if (vNetData.PlayerID == PlayerDatas.Instance.baseData.PlayerID)
-            {
-                return;
-            }
-        }
-        ChatFriendData chatData = new ChatFriendData(vNetData.Content, (int)vNetData.PlayerID, vNetData.SrcName, vNetData.Extras, vNetData.ToName, vNetData.TalkType, vNetData.ToPlayerID);
-        FitterChat(chatData);
-        AddPteChat(chatData, false);
-        LocalChatHistory.Save(chatData as ChatUeseData);
-        if (chatData.player == PlayerDatas.Instance.baseData.PlayerID)
-        {
-            if (OnRefreshSelf != null)
-            {
-                OnRefreshSelf(chatData);
-            }
-        }
-        if (chatData.IsSound)
-        {
-            // ChatCenter.Instance.CheckAutoPlayVoice(chatData);
-        }
-    }
-    private void AddPteChat(ChatFriendData chatData, bool isLocal)
-    {
-        List<ChatFriendData> list = null;
-        pteChatDics.TryGetValue(chatData.player + chatData.toPlayer, out list);
-        if (list != null)
-        {
-            if (list.Count > CHAT_INFO_CNT)
-            {
-                ChatUeseData outData = list[0];
-                list.RemoveAt(0);
-                outData = null;
-            }
-            list.Add(chatData);
+            return 2;
         }
         else
         {
-            list = new List<ChatFriendData>();
-            list.Add(chatData);
-            pteChatDics.Add(chatData.player + chatData.toPlayer, list);
-        }
-        if (OnRefreshPteChat != null && !isLocal)
-        {
-            OnRefreshPteChat(chatData);
-        }
-    }
-    /// <summary>
-    /// 闃熶紞棰戦亾
-    /// </summary>
-    /// <param name="vNetData"></param>
-    public void RevChatInfo(H0205_tagTalkDui vNetData)
-    {
-        ChatData chatData = new ChatTeamData(vNetData.Content, (int)vNetData.PlayerID, vNetData.Name, vNetData.Extras);
-        KeepChatInfo(chatData);
-        ReceiveNewChat(ChatInfoType.Team);
-    }
-    /// <summary>
-    /// GM
-    /// </summary>
-    /// <param name="vNetData"></param>
-    public void RevChatInfo(H3202_tagServerResponse vNetData)
-    {
-        ChatData chatData = new ChatSystemData(vNetData.Message);
-        KeepChatInfo(chatData);
-    }
-    /// <summary>
-    /// 绯荤粺鎻愮ず
-    /// </summary>
-    /// <param name="msg"></param>
-    public void RevChatInfo(string msg)
-    {
-        ChatData chatData = new ChatSystemData(msg);
-        KeepChatInfo(chatData);
-    }
-    public void RevChatInfo(string msg, ArrayList infoList, ChatInfoType type = ChatInfoType.System)
-    {
-        ChatData chatData = null;
-        switch (type)
-        {
-            case ChatInfoType.System:
-                {
-                    chatData = new ChatSystemData(msg);
-                    chatData.infoList.AddRange(infoList);
-                }
-                break;
-            case ChatInfoType.FairyTip:
-            case ChatInfoType.FairyQuestion:
-                {
-                    chatData = new ChatFamilyData(msg, 0, string.Empty, string.Empty, type);
-                    chatData.infoList.AddRange(infoList);
-                }
-                break;
-            case ChatInfoType.TeamTip:
-                {
-                    chatData = new ChatTeamData(msg, 0, string.Empty, string.Empty, type);
-                    chatData.infoList.AddRange(infoList);
-                }
-                break;
-            case ChatInfoType.default1:
-            case ChatInfoType.default2:
-                {
-                    chatData = new ChatFactionData(msg, 0, string.Empty, string.Empty, type);
-                    chatData.infoList.AddRange(infoList);
-                }
-                break;
-        }
-        if (chatData != null)
-        {
-            KeepChatInfo(chatData);
-        }
-    }
-    /// <summary>
-    /// 鑾峰彇棰戦亾鑱婂ぉ鏁版嵁
-    /// </summary>
-    /// <param name="type"></param>
-    /// <returns></returns>
-    public List<ChatData> GetChatInfo(ChatInfoType type)
-    {
-        List<ChatData> list = null;
-        chatDics.TryGetValue(type, out list);
-        return list;
-    }
-    /// <summary>
-    /// 鑾峰彇濂藉弸鑱婂ぉ鏁版嵁
-    /// </summary>
-    /// <param name="type"></param>
-    /// <returns></returns>
-    public List<ChatFriendData> GetChatInfo(int player)
-    {
-        List<ChatFriendData> list = null;
-        pteChatDics.TryGetValue(player + (int)PlayerDatas.Instance.baseData.PlayerID, out list);
-        return list;
-    }
-    /// <summary>
-    /// 鑾峰彇涓荤晫闈㈢殑鑱婂ぉ鏁版嵁
-    /// </summary>
-    /// <returns></returns>
-    public List<ChatData> GetChatInfo()
-    {
-        return chatlist;
-    }
-    public List<ChatData> GetChatUpInfo()
-    {
-        return chatUpList;
-    }
-    public ChatData GetChatInfo(ChatInfoType type, int index)
-    {
-        List<ChatData> list = null;
-        chatDics.TryGetValue(type, out list);
-        if (list != null)
-        {
-            return list[index];
-        }
-        return null;
-    }
-
-    public void KeepLocalChat(ChatData chat)
-    {
-        if (chat.type == ChatInfoType.Friend)
-        {
-            FitterChat(chat);
-            AddPteChat(chat as ChatFriendData, true);
-        }
-        else
-        {
-            KeepChatInfo(chat);
+            return 3;
         }
     }
 
-    private void KeepChatInfo(ChatData data)
-    {
-        KeepAllTypeChat(data);
-        List<ChatData> list = null;
-        chatDics.TryGetValue(data.type, out list);
-        if (list != null)
-        {
-            if (list.Count >= CHAT_INFO_CNT)
-            {
-                ChatData outData = list[0];
-                list.RemoveAt(0);
-                outData = null;
-            }
-            list.Add(data);
-        }
-        else
-        {
-            list = new List<ChatData>();
-            list.Add(data);
-            chatDics.Add(data.type, list);
-        }
-        if (chatFloatUpdate != null)
-        {
-            chatFloatUpdate(data);
-        }
-        if (OnRefreshChat != null)
-            OnRefreshChat(data.type);
-        if (data.type != ChatInfoType.System && (data as ChatUeseData).player == PlayerDatas.Instance.baseData.PlayerID)
-        {
-            if (OnRefreshSelf != null)
-                OnRefreshSelf(data);
-        }
-        // if ((data is ChatUeseData)
-        //     && (data as ChatUeseData).IsSound)
-        // {
-        //     ChatCenter.Instance.CheckAutoPlayVoice(data);
-        // }
-    }
-    private void KeepAllTypeChat(ChatData data)
-    {
-        if (!FitterChat(data))
-        {
-            if (chatlist.Count >= CHAT_TIP_CNT)
-            {
-                ChatData outData = chatlist[0];
-                chatlist.RemoveAt(0);
-            }
-            if (chatUpList.Count >= CHAT_INFO_CNT)
-            {
-                ChatData outData = chatUpList[0];
-                chatUpList.RemoveAt(0);
-            }
-            chatlist.Add(data);
-            chatUpList.Add(data);
-        }
-    }
-    private bool FitterChat(ChatData data)
-    {
-        if (data.type == ChatInfoType.System)
-        {
-            return true;
-        }
-
-        if (IsItemChat(data.content))
-        {
-            string content = data.content;
-            MatchCollection matchArray = HrefAnalysis.EquipDetailRegex.Matches(content);
-            int index = 0;
-            for (int i = 0; i < matchArray.Count; i++)
-            {
-                data.richText.Append(content.Substring(index, matchArray[i].Index - index));
-                index = matchArray[i].Index + matchArray[i].Length;
-                string detail = matchArray[i].Groups[1].Value;
-                var itemplusArray = detail.Split('|');
-                if (itemplusArray.Length > 1)
-                {
-                    var itemId = int.Parse(itemplusArray[0]);
-                    ItemConfig itemConfig = ItemConfig.Get(itemId);
-                    if (itemConfig != null)
-                    {
-                        try
-                        {
-                            int[] equipGems = null;
-                            if (itemplusArray.Length >= 8)
-                            {
-                                equipGems = new int[4];
-                                for (int j = 0; j < equipGems.Length; j++)
-                                {
-                                    equipGems[j] = int.Parse(itemplusArray[4 + j]);
-                                }
-                            }
-
-                            ItemTipUtility.CustomEquipWash equipWash = new ItemTipUtility.CustomEquipWash();
-                            if (itemplusArray.Length >= 15)
-                            {
-                                equipWash.LV = int.Parse(itemplusArray[11]);
-                                equipWash.Value = new int[3];
-                                equipWash.Value[0] = int.Parse(itemplusArray[12]);
-                                equipWash.Value[1] = int.Parse(itemplusArray[13]);
-                                equipWash.Value[2] = int.Parse(itemplusArray[14]);
-                            }
-
-                            List<int> suitPlaces = null;
-                            if (itemplusArray.Length > 15)
-                            {
-                                suitPlaces = new List<int>();
-                                for (int j = 0; j < 8; j++)
-                                {
-                                    var place = int.Parse(itemplusArray[15 + j]);
-                                    if (place != 0)
-                                    {
-                                        suitPlaces.Add(place);
-                                    }
-                                }
-                            }
-
-                            int[] suitLevels = null;
-                            if (itemplusArray.Length > 15)
-                            {
-                                suitLevels = new int[3];
-                                for (int j = 0; j < 3; j++)
-                                {
-                                    suitLevels[j] = int.Parse(itemplusArray[23 + j]);
-                                }
-                            }
-
-                            int[] placeStars = null;
-                            if (itemplusArray.Length > 15)
-                            {
-                                placeStars = new int[8];
-                                for (int j = 0; j < 8; j++)
-                                {
-                                    placeStars[j] = int.Parse(itemplusArray[26 + j]);
-                                }
-                            }
-
-
-                            ItemTipUtility.CustomItemPlus itemplus = new ItemTipUtility.CustomItemPlus()
-                            {
-                                ItemID = itemId,
-                                count = int.Parse(itemplusArray[1]),
-                                Equipped = int.Parse(itemplusArray[2]),
-                                UserData = itemplusArray[3],
-                                Stone = equipGems,
-                                PlusLV = itemplusArray.Length >= 9 ? int.Parse(itemplusArray[8]) : 0,
-                                Star = itemplusArray.Length >= 10 ? int.Parse(itemplusArray[9]) : 0,
-                                EvolveLV = itemplusArray.Length >= 11 ? int.Parse(itemplusArray[10]) : 0,
-                                Wash = equipWash,
-                                Equips = null,
-                                suitPlaces = suitPlaces == null ? null : suitPlaces.ToArray(),
-                                suitLevels = suitLevels,
-                                placeStars = placeStars,
-                            };
-
-                            string append = string.Format("<a><Word info=item id={0} itemplus={1} chatsend=1/>|showitem={0} itemplus={1}</a>",
-                                      itemId, LitJson.JsonMapper.ToJson(itemplus));
-                            append = UIHelper.AppendColor(itemConfig.ItemColor, append);
-                            data.richText.Append(append);
-                        }
-                        catch (Exception e)
-                        {
-                            data.richText.Append(itemConfig.ItemName);
-                            Debug.Log(e.Message);
-                        }
-                    }
-                }
-                else
-                {
-                    data.richText.Append(matchArray[i].Value);
-                }
-            }
-            data.richText.Append(content.Substring(index, content.Length - index));
-        }
-        if (data.type == ChatInfoType.Friend)
-        {
-            return true;
-        }
-        if (data.content.Equals(string.Empty))
-        {
-            return true;
-        }
-        return !chatOpenDics[data.type];
-    }
-    public Dictionary<ChatInfoType, bool> GetChatOpen()
-    {
-        return chatOpenDics;
-    }
-
-    #region 缁勯槦閭�璇�
-    private const string INVITE_IDENTIFY = "<i>";
-    public static Regex InviteRegex = new Regex(@INVITE_IDENTIFY, RegexOptions.Singleline);
-    public void SendInvite(string msg)
-    {
-        SendChatInfo(ChatInfoType.World, StringUtility.Contact(msg, INVITE_IDENTIFY));
-    }
-    public bool IsInviteChat(string msg)
-    {
-        return InviteRegex.IsMatch(msg);
-    }
-    #endregion
-
-    #region 鍙戦�佺墿鍝�
-    public List<ItemModel> itemPlaceList = new List<ItemModel>();
-    public bool IsItemChat(string msg)
-    {
-        return HrefAnalysis.EquipDetailRegex.IsMatch(msg);
-    }
-    public string CheckHasItem(string msg, ChatCenter.RecentlyChat _recently)
-    {
-        return string.Empty;
-        // if (!HrefAnalysis.EquipRegex.IsMatch(msg))
-        // {
-        //     return msg;
-        // }
-        // sb.Length = 0;
-        // MatchCollection matchArray = HrefAnalysis.EquipRegex.Matches(msg);
-        // int index = 0;
-        // for (int i = 0; i < matchArray.Count; i++)
-        // {
-        //     sb.Append(msg.Substring(index, matchArray[i].Index - index));
-        //     if (ChatCenter.Instance.recentlyChat != null)
-        //     {
-        //         if (i < ChatCenter.Instance.recentlyChat.itemIndexs.Count)
-        //         {
-        //             var _index = ChatCenter.Instance.recentlyChat.itemIndexs[i];
-        //             sb.Append(" ");
-        //             sb.Append(ChatCenter.Instance.recentlyChat.itemInfos[_index]);
-        //             sb.Append(" ");
-        //         }
-        //         index = matchArray[i].Index + matchArray[i].Length;
-        //         continue;
-        //     }
-        //     var _length = sb.Length;
-        //     if (i < itemPlaceList.Count)
-        //     {
-        //         var itemConfig = ItemConfig.Get((int)itemPlaceList[i].itemId);
-        //         if (itemConfig.ItemName == matchArray[i].Groups[1].Value)
-        //         {
-        //             bool equip = itemPlaceList[i].packType == PackType.Equip;
-
-        //             sb.Append("#item#");
-        //             AppendValue(sb, itemPlaceList[i].itemId);
-        //             AppendValue(sb, itemPlaceList[i].count);
-        //             AppendValue(sb, equip ? 1 : 0);
-        //             AppendValue(sb, itemPlaceList[i].itemInfo.userData);
-
-        //             if (equip)
-        //             {
-        //                 var position = new Int2(itemConfig.LV, itemConfig.EquipPlace);
-
-        //                 int[] equipGems;
-        //                 equipGemModel.TryGetEquipGems(itemPlaceList[i].gridIndex, out equipGems);
-        //                 for (int j = 0; j < EquipGemModel.EQUIPGEM_HOLE_COUNT; j++)
-        //                 {
-        //                     AppendValue(sb, equipGems != null && j < equipGems.Length ? equipGems[j] : 0);
-        //                 }
-
-        //                 var strengthLevel = equipStrengthModel.GetStrengthLevel(itemConfig.LV, itemConfig.EquipPlace);
-        //                 AppendValue(sb, strengthLevel);
-
-        //                 var starLevel = equipStarModel.GetEquipStarLevel(new Int2(itemConfig.LV, itemConfig.EquipPlace));
-        //                 AppendValue(sb, starLevel);
-
-        //                 var evolveLevel = equipStrengthModel.GetStrengthEvolveLevel(position.x, position.y);
-        //                 AppendValue(sb, evolveLevel);
-
-        //                 AppendValue(sb, equipTrainModel.GetTrainLevel(position));
-
-        //                 var property = equipTrainModel.GetTrainedProperties(position);
-        //                 AppendValue(sb, property.x);
-        //                 AppendValue(sb, property.y);
-        //                 AppendValue(sb, property.z);
-
-        //                 for (int place = 1; place <= 12; place++)
-        //                 {
-        //                     if (place > 8)
-        //                     {
-        //                         continue;
-        //                     }
-        //                     var equipGuid = equipModel.GetEquip(new Int2(position.x, place));
-        //                     if (!string.IsNullOrEmpty(equipGuid))
-        //                     {
-        //                         var equipItem = packManager.GetItemByGuid(equipGuid);
-        //                         if (equipItem.config.SuiteiD > 0)
-        //                         {
-        //                             AppendValue(sb, place);
-        //                             continue;
-        //                         }
-        //                     }
-        //                     AppendValue(sb, 0);
-        //                 }
-
-        //                 AppendValue(sb, equipModel.GetSuitLevel(itemConfig.LV, EquipSuitType.TwoSuit));
-        //                 AppendValue(sb, equipModel.GetSuitLevel(itemConfig.LV, EquipSuitType.FiveSuit));
-        //                 AppendValue(sb, equipModel.GetSuitLevel(itemConfig.LV, EquipSuitType.EightSuit));
-
-        //                 for (int place = 1; place <= 8; place++)
-        //                 {
-        //                     var equipGuid = equipModel.GetEquip(new Int2(position.x, place));
-        //                     if (!string.IsNullOrEmpty(equipGuid))
-        //                     {
-        //                         var equipItem = packManager.GetItemByGuid(equipGuid);
-        //                         if (ItemLogicUtility.Instance.IsSuitEquip(equipItem.itemId))
-        //                         {
-        //                             AppendValue(sb, equipStarModel.GetStarLevel(new Int2(position.x, place)));
-        //                         }
-        //                         else
-        //                         {
-        //                             AppendValue(sb, -1);
-        //                         }
-        //                     }
-        //                     else
-        //                     {
-        //                         AppendValue(sb, -1);
-        //                     }
-        //                 }
-        //             }
-
-        //             sb.Remove(sb.Length - 1, 1);
-        //             sb.Append("#item#");
-
-        //             if (_recently != null)
-        //             {
-        //                 _recently.Add(itemConfig.ItemName, sb.ToString().Substring(_length));
-        //             }
-        //         }
-        //         else
-        //         {
-        //             sb.Append(matchArray[i].Value);
-        //         }
-        //     }
-        //     else
-        //     {
-        //         sb.Append(matchArray[i].Value);
-        //     }
-        //     index = matchArray[i].Index + matchArray[i].Length;
-        // }
-        // sb.Append(msg.Substring(index, msg.Length - index));
-        // return sb.ToString();
-    }
-
-    void AppendValue(StringBuilder sb, object _object)
-    {
-        sb.Append(_object);
-        sb.Append('|');
-    }
-    #endregion
-
-    #region 濂藉弸绉佽亰
-    public static Regex KillRegex = new Regex(@KILL_IDENTIFY, RegexOptions.Singleline);
-    public const string KILL_IDENTIFY = "<k>";
-    public void SendFriendChat(string msg, int player)
-    {
-        C0209_tagCTalkMiFix chatPack = new C0209_tagCTalkMiFix();
-        chatPack.TalkType = 1;
-        chatPack.PlayerID = (uint)player;
-        chatPack.Len = (ushort)GetUTF8InfoLen(msg);
-        chatPack.Content = msg;
-        GameNetSystem.Instance.SendInfo(chatPack);
-    }
-    #endregion
-    /// <summary>
-    /// 娓呭睆
-    /// </summary>
-    public void ClearAllChatInfo()
-    {
-        chatDics.Clear();
-        chatlist.Clear();
-        chatUpList.Clear();
-        pteChatDics.Clear();
-        if (OnRefreshChat != null)
-        {
-            OnRefreshChat(presentChatType);
-        }
-    }
-
-    public void ClearChatInfo(ChatInfoType type)
-    {
-        List<ChatData> list = null;
-        if (chatDics.TryGetValue(type, out list))
-        {
-            list.Clear();
-            if (OnRefreshChat != null)
-            {
-                OnRefreshChat(type);
-            }
-        }
-    }
 
     public static int GetUTF8InfoLen(string msg)
     {
         return Encoding.UTF8.GetBytes(msg).Length;
     }
 
-    public void CloseChatBtnClick()
+    public bool TryGetBubble(int id, out ChatBubbleData bubble)
     {
-        if (OnClickCloseChatEvent != null)
-        {
-            OnClickCloseChatEvent();
-        }
+        return chatBubbles.TryGetValue(id, out bubble);
     }
 
-    public bool IsExtentOpen { get; set; }
-    public void OpenChatExtent(bool open)
+    void ParseChatBubbleConfig()
     {
-        if (OnChatExtentOpenEvent != null)
+        var configs = ChatBubbleBoxConfig.GetValues();
+        for (int i = 0; i < configs.Count; i++)
         {
-            OnChatExtentOpenEvent(open);
-        }
-    }
-
-    #region 闄岀敓浜鸿亰澶�
-    public event Action OpenPteChatEvent;
-    public void OpenFriendWin()
-    {
-        if (OpenPteChatEvent != null)
-        {
-            OpenPteChatEvent();
-        }
-    }
-    #endregion
-
-    #region 涓荤晫闈㈣亰澶╅閬撴樉绀鸿缃�
-    public void SetChatChannelShow(ChatInfoType type, bool open)
-    {
-        if (chatOpenDics.ContainsKey(type))
-        {
-            chatOpenDics[type] = open;
-        }
-    }
-
-    public void GetChatChannelShow()
-    {
-        chatOpenDics[ChatInfoType.World] = ChatSetting.Instance.GetBool(ChatBoolType.ChannelWorld);
-        chatOpenDics[ChatInfoType.Area] = ChatSetting.Instance.GetBool(ChatBoolType.ChannelArea);
-        chatOpenDics[ChatInfoType.Fairy] = ChatSetting.Instance.GetBool(ChatBoolType.ChannelGrad);
-        chatOpenDics[ChatInfoType.Invite] = ChatSetting.Instance.GetBool(ChatBoolType.ChannelATeam);
-        chatOpenDics[ChatInfoType.System] = ChatSetting.Instance.GetBool(ChatBoolType.ChannelSystem);
-        chatOpenDics[ChatInfoType.Team] = ChatSetting.Instance.GetBool(ChatBoolType.ChannelTeam);
-        chatOpenDics[ChatInfoType.Trumpet] = ChatSetting.Instance.GetBool(ChatBoolType.ChannelBugle);
-        chatOpenDics[ChatInfoType.CrossServer] = true;
-        chatOpenDics[ChatInfoType.default1] = true;
-    }
-    #endregion
-
-    #region 鏃ュ父璺宠浆
-    private string[] realmRandomChats = new string[2] { "DailyQuestRealmTalk1", "DailyQuestRealmTalk2" };
-    private string[] dungeonRandomChats = new string[2] { "DailyQuestAssitmTalk1", "DailyQuestAssitmTalk2" };
-    public bool openFromDaily { get; set; }
-    public string GetAssitRandomChat(ChatInfoType _type)
-    {
-        int _index = UnityEngine.Random.Range(0, 2);
-        switch (_type)
-        {
-            case ChatInfoType.World:
-                if (_index == 0)
-                {
-                    return Language.Get(dungeonRandomChats[0]);
-                }
-                else
-                {
-                    return Language.Get(dungeonRandomChats[1], PlayerDatas.Instance.baseData.FightPower);
-                }
-            case ChatInfoType.Fairy:
-                return Language.Get(realmRandomChats[_index]);
-        }
-        return string.Empty;
-    }
-
-    public bool openFromFairyTask { get; set; }
-    Dictionary<int, List<string>> m_TaskRandomChats = new Dictionary<int, List<string>>();
-    public string GetTaskRandomChat(ChatInfoType _type)
-    {
-        if (m_TaskRandomChats.ContainsKey((int)_type))
-        {
-            var list = m_TaskRandomChats[(int)_type];
-            var index = UnityEngine.Random.Range(0, list.Count);
-            return Language.Get(list[index]);
-        }
-        return string.Empty;
-    }
-
-    public bool needCheckAssitChat { get; set; }
-    public int IsAssitChat(string message, bool force = false)
-    {
-        int assitChat = 0;
-        if (needCheckAssitChat || force)
-        {
-            for (int i = 0; i < 2; i++)
+            var config = configs[i];
+            if (chatBubbles.ContainsKey(config.ID))
             {
-                if (message.Equals(Language.Get(realmRandomChats[i])))
+                continue;
+            }
+            var bubble = new ChatBubbleData();
+            bubble.id = config.ID;
+            bubble.leftPadding = new RectOffset()
+            {
+                left = config.LeftOffset.Length > 0 ? config.LeftOffset[0] : 0,
+                right = config.LeftOffset.Length > 1 ? config.LeftOffset[1] : 0,
+                top = config.LeftOffset.Length > 2 ? config.LeftOffset[2] : 0,
+                bottom = config.LeftOffset.Length > 3 ? config.LeftOffset[3] : 0,
+            };
+            bubble.rifhtPadding = new RectOffset()
+            {
+                left = config.RightOffset.Length > 0 ? config.RightOffset[0] : 0,
+                right = config.RightOffset.Length > 1 ? config.RightOffset[1] : 0,
+                top = config.RightOffset.Length > 2 ? config.RightOffset[2] : 0,
+                bottom = config.RightOffset.Length > 3 ? config.RightOffset[3] : 0,
+            };
+            bubble.myColor = new Color32()
+            {
+                r = (byte)(config.MyColor.Length > 0 ? config.MyColor[0] : 0),
+                g = (byte)(config.MyColor.Length > 1 ? config.MyColor[1] : 0),
+                b = (byte)(config.MyColor.Length > 2 ? config.MyColor[2] : 0),
+                a = (byte)(config.MyColor.Length > 3 ? config.MyColor[3] : 255),
+            };
+            bubble.otherColor = new Color32()
+            {
+                r = (byte)(config.OtherColor.Length > 0 ? config.OtherColor[0] : 0),
+                g = (byte)(config.OtherColor.Length > 1 ? config.OtherColor[1] : 0),
+                b = (byte)(config.OtherColor.Length > 2 ? config.OtherColor[2] : 0),
+                a = (byte)(config.OtherColor.Length > 3 ? config.OtherColor[3] : 255),
+            };
+            bubble.top = config.Top;
+            chatBubbles.Add(config.ID, bubble);
+        }
+    }
+    public bool SatisfyNameLength(string name, out int error)
+    {
+        error = 0;
+        int length = Encoding.Default.GetBytes(name).Length;
+        int maxlength = characterLimit;  //绾腑鏂囧瓧鏁�
+        //var minlength = 3;
+        if (length > maxlength)
+        {
+            error = 1;
+        }
+        // else if (length < minlength)
+        // {
+        //     error = 2;
+        // }
+        return error == 0;
+    }
+    public bool CheckChatLimit(string info, out int errorCode)
+    {
+        errorCode = 0;
+        if (string.IsNullOrEmpty(info))
+        {
+            errorCode = 0;
+            return false;
+        }
+
+        if (!SatisfyNameLength(info, out errorCode))
+        {
+            return false;
+        }
+
+        if (DirtyWordConfig.IsDirtWord(info) || UIHelper.HasSpecialCharac(info)
+            || DirtyNameConfig.IsDirtName(info))
+        {
+            errorCode = 3;
+            return false;
+        }
+        return true;
+    }
+
+    public void ShowChatErrorTip(int _errorCode)
+    {
+        switch (_errorCode)
+        {
+            case 0:
+                //绌�
+                SysNotifyMgr.Instance.ShowTip("ChatInfoNoNull");
+                break;
+            case 1:
+                // 闀垮害杩囬暱
+                SysNotifyMgr.Instance.ShowTip("NameError2", 7);
+                break;
+            case 3:
+                // 鑴忓瓧
+                SysNotifyMgr.Instance.ShowTip("NameSensitive");
+                break;
+        }
+    }
+
+
+    public int GetJumpIndex(ChatChannel type)
+    {
+        if (!TryGetTalkData(type, out List<TalkData> datas))
+            return 0;
+        return Mathf.Max(datas.Count - 1, 0);
+    }
+
+    public bool IsValidChatChannel(int channelType)
+    {
+        return Enum.IsDefined(typeof(ChatChannel), channelType);
+    }
+
+    public bool TryGetChatData(ChatChannel type, int index, out TalkData data)
+    {
+        data = null;
+        if (!TryGetTalkData(type, out List<TalkData> datas) || datas == null)
+            return false;
+        if (index < 0 || index >= datas.Count)
+            return false;
+        data = datas[index];
+        return true;
+    }
+
+    public bool TryGetTalkData(ChatChannel type, out List<TalkData> datas)
+    {
+        return talkDict.TryGetValue(type, out datas);
+    }
+
+    public void SendChatInfo(ChatChannel type, string content)
+    {
+        SendChatPack((int)type, content);
+    }
+    public void SendChatPack(int channelType, string content)
+    {
+        CB320_tagCSTalk pack = new CB320_tagCSTalk();
+        pack.ChannelType = (byte)channelType;
+        pack.Content = content;
+        pack.Len = (ushort)GetUTF8InfoLen(content);
+        GameNetSystem.Instance.SendInfo(pack);
+    }
+
+    public readonly int maxTalkCount = 1000;  //鑱婂ぉ鏁伴噺涓婇檺
+    public readonly int deleteTalkCount = 300;  //鑱婂ぉ鏁伴噺涓婇檺鏃跺垹闄ゅ墠澶氬皯鏉�
+
+    void TryDeleteTalkData(ChatChannel type)
+    {
+        if (!TryGetTalkData(type, out List<TalkData> datas))
+            return;
+        if (datas.Count < maxTalkCount)
+            return;
+        datas.RemoveRange(0, deleteTalkCount);
+    }
+
+    public int currentDay = -1;
+    public void AddTalkData(ChatChannel type, TalkData data)
+    {
+        //濡傛灉瓒呰繃闄愬埗鍏堝垹闄ゆ棫鏁版嵁
+        TryDeleteTalkData(type);
+        if (!TryGetTalkData(type, out List<TalkData> datas))
+        {
+            talkDict[type] = new List<TalkData>();
+        }
+        talkDict[type].Add(data);
+        OnUpdateTalkEvent?.Invoke(type, data);
+    }
+
+    public bool TryAddDate(int allSeconds, ChatChannel type)
+    {
+        DateTime talkTime = TimeUtility.GetTime((uint)allSeconds);
+        if (talkTime.Day != currentDay)
+        {
+            currentDay = talkTime.Day;
+            AddTalkData(type, new TalkData()
+            {
+                ChannelType = (byte)type,
+                isDate = true,
+                Content = Language.Get("Chat09", talkTime.Month, talkTime.Day),
+                TalkTime = (uint)allSeconds,
+            });
+            return true;
+        }
+        return false;
+    }
+
+    public void AddSysData(string msg, ArrayList infoList, ChatChannel type)
+    {
+        int allSeconds = TimeUtility.AllSeconds;
+        // 濡傛灉闅斿ぉ,澧炲姞鏃ユ湡琛�
+        TryAddDate(allSeconds, type);
+
+        if (!talkDict.ContainsKey(type))
+        {
+            talkDict[type] = new List<TalkData>();
+        }
+        AddTalkData(type, new TalkData()
+        {
+            ChannelType = (byte)type,
+            isSystem = true,
+            Content = msg,
+            BubbleBox = 1,
+            TalkTime = (uint)allSeconds,
+            InfoList = new ArrayList(infoList),
+        });
+    }
+
+    public void UpdateTalk(HB310_tagMCTalk vNetData)
+    {
+        if (!IsValidChatChannel(vNetData.ChannelType))
+            return;
+
+        ChatChannel type = (ChatChannel)vNetData.ChannelType;
+        if (!talkDict.ContainsKey(type))
+        {
+            talkDict[type] = new List<TalkData>();
+        }
+
+        int allSeconds = TimeUtility.AllSeconds;
+        // 濡傛灉闅斿ぉ,澧炲姞鏃ユ湡琛�
+        TryAddDate(allSeconds, type);
+
+        TalkData talkData = new TalkData()
+        {
+            ChannelType = vNetData.ChannelType,
+            Name = UIHelper.ServerStringTrim(vNetData.Name),
+            PlayerID = vNetData.PlayerID,
+            Content = UIHelper.ServerStringTrim(vNetData.Content),
+            BubbleBox = vNetData.BubbleBox,
+            LV = vNetData.LV,
+            RealmLV = vNetData.RealmLV,
+            TitleID = vNetData.TitleID,
+            Job = vNetData.Job,
+            Face = vNetData.Face,
+            FacePic = vNetData.FacePic,
+            ServerID = vNetData.ServerID,
+            TalkTime = (uint)allSeconds,
+        };
+        AddTalkData(type, talkData);
+    }
+
+    public void UpdateTalkCacheList(HB311_tagMCTalkCacheList vNetData)
+    {
+        if (!IsValidChatChannel(vNetData.ChannelType))
+            return;
+
+        ChatChannel type = (ChatChannel)vNetData.ChannelType;
+        if (!talkDict.ContainsKey(type))
+        {
+            talkDict[type] = new List<TalkData>();
+        }
+
+        if (vNetData.InfoList.IsNullOrEmpty())
+            return;
+
+        foreach (var info in vNetData.InfoList)
+        {
+            // 濡傛灉闅斿ぉ,澧炲姞鏃ユ湡琛�
+            TryAddDate((int)info.TalkTime, type);
+            AddTalkData(type, new TalkData()
+            {
+                ChannelType = vNetData.ChannelType,
+                Name = info.Name,
+                PlayerID = info.PlayerID,
+                Content = info.Content,
+                BubbleBox = info.BubbleBox,
+                LV = info.LV,
+                Job = info.Job,
+                RealmLV = info.RealmLV,
+                TitleID = info.TitleID,
+                Face = info.Face,
+                FacePic = info.FacePic,
+                ServerID = info.ServerID,
+                TalkTime = info.TalkTime,
+            });
+        }
+        OnUpdateTalkCacheListEvent?.Invoke();
+    }
+    #region 鏍囩椤�
+    // 褰撳墠灞曠ず鐨勯閬撳叆鍙�
+    private ChatTab m_NowChatTab;
+    public ChatTab nowChatTab
+    {
+        get { return m_NowChatTab; }
+        set
+        {
+            if (m_NowChatTab == value)
+                return;
+            m_NowChatTab = value;
+            OnChatTabChangeEvent?.Invoke(value);
+        }
+    }
+
+    public event Action<ChatTab> OnChatTabChangeEvent;
+
+    // 棰戦亾鍏ュ彛鐨勫睍绀洪『搴�
+    public readonly List<ChatTab> tabShowList = new List<ChatTab>()
+    {
+        ChatTab.World,
+        ChatTab.Guild,
+        // ChatTab.Person,
+        // ChatTab.BlackList,
+    };
+
+    public bool IsTabOpen(ChatTab chatTab, bool isTip = false)
+    {
+        if (!tabShowList.Contains(chatTab))
+            return false;
+
+        switch (chatTab)
+        {
+            case ChatTab.World:
+                return true;
+            case ChatTab.Guild:
+                //娌℃湁鍏細
+                if (!PlayerDatas.Instance.fairyData.HasFairy)
                 {
-                    assitChat = 1;
-                    break;
+                    if (isTip)
+                        SysNotifyMgr.Instance.ShowTip("NoGuild");
+                    return false;
                 }
-                if (message.Equals(Language.Get(dungeonRandomChats[i])))
-                {
-                    assitChat = 2;
-                    break;
-                }
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    public bool IsSelectChatTab(ChatTab chatTab)
+    {
+        return nowChatTab == chatTab;
+    }
+
+    public bool IsValidChatTab(int chatTab)
+    {
+        return Enum.IsDefined(typeof(ChatTab), chatTab);
+    }
+
+    public string GetChatTabName(ChatTab chatTab)
+    {
+        return Language.Get(StringUtility.Contact("ChatTab", (int)chatTab));
+    }
+
+    public string GetChatTabSelectIcon(ChatTab chatTab, bool isSelect)
+    {
+        return StringUtility.Contact(isSelect ? "ChatTabSelect" : "ChatTabUnSelect", (int)chatTab);
+    }
+    #endregion
+    #region 寮瑰箷璁剧疆
+
+    private Dictionary<ChatChannel, bool> bulletSettingDict = new Dictionary<ChatChannel, bool>();
+
+    private string settingsKey { get { return StringUtility.Contact("BulletChatSettings_", PlayerDatas.Instance.PlayerId); } }
+
+    // 璁剧疆鐗瑰畾棰戦亾鐨勫脊骞曞紑鍏崇姸鎬�
+    public void SetBulletSetting(ChatChannel channelType, bool isEnabled)
+    {
+        bulletSettingDict[channelType] = isEnabled;
+        SaveBulletSettings();
+    }
+
+    // 鑾峰彇鐗瑰畾棰戦亾鐨勫脊骞曞紑鍏崇姸鎬�
+    public bool GetBulletSetting(ChatChannel channelType)
+    {
+        if (bulletSettingDict.TryGetValue(channelType, out bool value))
+        {
+            return value;
+        }
+        return true;
+    }
+
+    // 淇濆瓨寮瑰箷璁剧疆鍒版湰鍦�
+    private void SaveBulletSettings()
+    {
+        Dictionary<int, int> saveDict = new Dictionary<int, int>();
+        foreach (var kvp in bulletSettingDict)
+        {
+            saveDict[(int)kvp.Key] = kvp.Value ? 1 : 0;
+        }
+        string jsonStr = JsonMapper.ToJson(saveDict);
+        LocalSave.SetString(settingsKey, jsonStr);
+    }
+
+    // 浠庢湰鍦拌鍙栧脊骞曡缃�
+    private void LoadBulletSettings()
+    {
+        bulletSettingDict.Clear();
+
+        // 浣跨敤 LocalSave 璇诲彇 JSON 瀛楃涓�
+        string jsonStr = LocalSave.GetString(settingsKey);
+
+        if (string.IsNullOrEmpty(jsonStr) || jsonStr == "{}")
+        {
+            // 濡傛灉娌℃湁淇濆瓨鐨勬暟鎹紝璁剧疆榛樿鍊�
+            InitializeDefaultBulletSettings();
+            return;
+        }
+
+        Dictionary<int, int> loadDict = ConfigParse.ParseIntDict(jsonStr);
+        foreach (var kvp in loadDict)
+        {
+            if (Enum.IsDefined(typeof(ChatChannel), kvp.Key))
+            {
+                bulletSettingDict[(ChatChannel)kvp.Key] = kvp.Value == 1;
             }
         }
-        return assitChat;
+    }
+
+    // 鍒濆鍖栭粯璁ゅ脊骞曡缃� 榛樿鎵�鏈夐閬撳紑鍚�
+    private void InitializeDefaultBulletSettings()
+    {
+        foreach (ChatChannel channelType in Enum.GetValues(typeof(ChatChannel)))
+        {
+            bulletSettingDict[channelType] = true;
+        }
+        SaveBulletSettings();
     }
     #endregion
 
-    #region 瀹濈煶鐐��璺宠浆
-    public bool openFromGem { get; set; }
-    public int flauntGemId { get; set; }
-    public bool flauntGemBind { get; set; }
-    public string GetGemFlauntChat()
-    {
-        var config = ItemConfig.Get(flauntGemId);
-        if (config != null)
-        {
-            var itemInfo = new ItemInfo();
-            itemInfo.itemId = flauntGemId;
-            var item = new ItemModel(PackType.Item, itemInfo);
-            var tip = string.Format("[{0}]", config.ItemName);
-            itemPlaceList.Add(item);
-            return Language.Get("GemLookTalk", tip);
-        }
-        return string.Empty;
-    }
-    #endregion
-
-    #region 浠欑紭绾㈢偣
-    Dictionary<ChatInfoType, Redpoint> chatSocialRedpoints = new Dictionary<ChatInfoType, Redpoint>();
-    Dictionary<ChatInfoType, int> unReadChatCounts = new Dictionary<ChatInfoType, int>();
-    public void InitChatRedpoints()
-    {
-        chatSocialRedpoints.Add(ChatInfoType.Fairy, new Redpoint(MainRedDot.RedPoint_FriendChatKey, 2502));
-        chatSocialRedpoints.Add(ChatInfoType.Team, new Redpoint(MainRedDot.RedPoint_FriendChatKey, 2503));
-        unReadChatCounts.Add(ChatInfoType.Fairy, 0);
-        unReadChatCounts.Add(ChatInfoType.Team, 0);
-    }
-
-    public void ViewChat(ChatInfoType type)
-    {
-        if (unReadChatCounts.ContainsKey(type))
-        {
-            unReadChatCounts[type] = 0;
-            UpdateRedpoint(type);
-        }
-    }
-
-    void ReceiveNewChat(ChatInfoType type)
-    {
-        // TODO YYL
-        // switch (type)
-        // {
-        //     case ChatInfoType.Team:
-        //         if (!UIManager.Instance.IsOpened<TeamChatWin>()
-        //             && (!UIManager.Instance.IsOpened<ChatWin>() || presentChatType != ChatInfoType.Team))
-        //         {
-        //             unReadChatCounts[ChatInfoType.Team] = Mathf.Min(unReadChatCounts[ChatInfoType.Team] + 1, 99);
-        //         }
-        //         break;
-        //     case ChatInfoType.Fairy:
-        //         if (!UIManager.Instance.IsOpened<FairyChatWin>()
-        //             && (!UIManager.Instance.IsOpened<ChatWin>() || presentChatType != ChatInfoType.Fairy))
-        //         {
-        //             unReadChatCounts[ChatInfoType.Fairy] = Mathf.Min(unReadChatCounts[ChatInfoType.Fairy] + 1, 99);
-        //         }
-        //         break;
-        // }
-        UpdateRedpoint(type);
-    }
-
-    public void UpdateRedpoint(ChatInfoType type)
-    {
-        if (chatSocialRedpoints.ContainsKey(type))
-        {
-            var redpoint = chatSocialRedpoints[type];
-            if (unReadChatCounts[type] > 0)
-            {
-                redpoint.state = RedPointState.Quantity;
-                redpoint.count = unReadChatCounts[type];
-            }
-            else
-            {
-                redpoint.state = RedPointState.None;
-            }
-        }
-        var socialRed = MainRedDot.Instance.redPointFriendChat;
-        if (chatSocialRedpoints[ChatInfoType.Fairy].state == RedPointState.Quantity
-            || chatSocialRedpoints[ChatInfoType.Team].state == RedPointState.Quantity)
-        {
-            socialRed.count = unReadChatCounts[ChatInfoType.Fairy] > 0 ?
-                unReadChatCounts[ChatInfoType.Fairy] : unReadChatCounts[ChatInfoType.Team];
-        }
-        else
-        {
-            socialRed.count = 0;
-        }
-    }
-
-    public RedPointState GetSocialChatRedpoint(ChatInfoType type)
-    {
-        if (chatSocialRedpoints.ContainsKey(type))
-        {
-            return chatSocialRedpoints[type].state;
-        }
-        return RedPointState.None;
-    }
-    #endregion
-
-    #region 鍗忓姪鎰熻阿
-    public void SendThank2AssistPlayer(int playerId)
-    {
-        // TODO YYL
-        // if (PlayerDatas.Instance.baseData.LV >= assistThankLevelLimit.x)
-        // {
-        //     return;
-        // }
-        // var assistPlayerInfo = dungeonAssistModel.GetAssistPlayerInfo(playerId);
-        // if (assistPlayerInfo != null)
-        // {
-        //     if (assistPlayerInfo.LV >= assistThankLevelLimit.y)
-        //     {
-        //         return;
-        //     }
-        // }
-        // var languageKeyIndex = UnityEngine.Random.Range(0, assistThankLanguages.Count);
-        // if (assistThankLanguages.Count > 0)
-        // {
-        //     SendFriendChat(Language.Get(assistThankLanguages[languageKeyIndex]), playerId);
-        // }
-    }
-    #endregion
 }
-public struct ChatExtraData
+
+public enum ChatTab
 {
-    public int infoint1;
-    public ChatExtraData(int info1)
-    {
-        this.infoint1 = info1;
-    }
-
-    public static ChatExtraData Default {
-        get {
-            return new ChatExtraData(0);
-        }
-    }
+    World = 0,      //涓栫晫
+    Guild = 1,      //鍏細      
+    Person = 2,     //绉佽亰
+    BlackList = 3,  //榛戝悕鍗�
 }
-
-public enum ChatInfoType
+public enum ChatChannel
 {
-    System,//绯荤粺娑堟伅
-    World, //涓栫晫棰戦亾
-    Area,  //鍖哄煙棰戦亾
-    Team,  //闃熶紞
-    Invite,//缁勯槦
-    Trumpet,//鍠囧彮
-    Fairy,//浠欑洘
-    Friend,//绉佽亰
-    CrossServer,//璺ㄦ湇
-    FairyQuestion,
-    FairyTip,
-    TeamTip,
-
-    //鍚庣画IL寮�鍙戞坊鍔犻璁�
-    default1,   //闃佃惀锛堝湪璺ㄦ湇鍦板浘寰�璺ㄦ湇鍙戯級
-    default2,   //闃佃惀淇℃伅鎻愮ず
-    default3,
-    default4,
-    default5,
-    default6,
-    default7,
-    default8,
-    default9,
-    default10,
+    World = 0,          //涓栫晫
+    CrossServer = 1,    //璺ㄦ湇
+    Area = 2,           // 鍖哄煙
+    Guild = 3,          // 鍏細
+    Friend = 4,             // 濂藉弸
+    Team = 5,               //闃熶紞
+    Person = 6,             //绉佽亰
 }
+public class ChatBubbleData
+{
+    public int id;
+    public RectOffset leftPadding;
+    public RectOffset rifhtPadding;
+    public Color32 myColor;
+    public Color32 otherColor;
+    public int top;
+}
+
+public class TalkData
+{
+    public byte ChannelType;    // 0-涓栫晫锛�1-璺ㄦ湇锛�3- 浠欑洘	
+    public bool isSystem = false;       //绯荤粺娑堟伅
+    public bool isDate = false;          //鍒嗗壊鏃ユ湡
+    public byte NameLen;
+    public string Name;
+    public uint PlayerID;
+    public string Content;
+    public uint BubbleBox;    //鑱婂ぉ姘旀场妗�
+    public ushort LV;    //绛夌骇
+    public byte Job;    //鑱屼笟
+    public byte RealmLV;    //澧冪晫
+    public uint TitleID;    //绉板彿
+    public uint Face;    //鍩烘湰鑴稿瀷
+    public uint FacePic;    //澶村儚妗�
+    public uint ServerID;    //鎵�灞炲尯鏈岻D
+    public uint TalkTime;        //璇ヨ亰澶╁彂閫佹椂闂存埑
+    public ArrayList InfoList;     //闄勫姞淇℃伅
+}
\ No newline at end of file
diff --git a/Main/System/Chat/ChatPlayerMineCell.cs b/Main/System/Chat/ChatPlayerMineCell.cs
index 846df2b..a265049 100644
--- a/Main/System/Chat/ChatPlayerMineCell.cs
+++ b/Main/System/Chat/ChatPlayerMineCell.cs
@@ -1,71 +1,50 @@
 锘縰sing System.Collections;
 using UnityEngine;
 using UnityEngine.UI;
-using EnhancedUI.EnhancedScroller;
-    public class ChatPlayerMineCell : ScrollerUI
+public class ChatPlayerMineCell : MonoBehaviour
+{
+    [SerializeField] AvatarCell avatarCell;
+    [SerializeField] RectTransform m_avatarRect;
+    [SerializeField] OfficialTitleCell title;
+    [SerializeField] Text m_PlayerName;
+    [SerializeField] ChatBubbleBehaviour m_ChatBubble;
+    [SerializeField] float spacing = 5.0f;
+    ChatManager manager { get { return ChatManager.Instance; } }
+    public void Refresh(CellView cell)
     {
-        // [SerializeField] AvatarCell avatarCell;
-        [SerializeField] RectTransform m_avatarRect;
-        [SerializeField] Text m_VipLv;
-        [SerializeField] Text m_PlayerName;
-        [SerializeField] Text m_ChatTime;
-        [SerializeField] ChatBubbleBehaviour m_ChatBubble;
-        [SerializeField] float spacing = 5.0f;
+        if (!manager.TryGetChatData(ChatManager.Instance.nowChatChannel, cell.index, out TalkData data))
+            return;
 
-        // PhantasmPavilionModel phantasmPavilionModel { get { return ModelCenter.Instance.GetModel<PhantasmPavilionModel>(); } }
-        public override void Refresh(CellView cell)
+        m_ChatBubble.DisplayContent(data.Content);
+
+        int bubbleID = ChatBubbleHelper.GetMyChatBubbleID();
+        m_ChatBubble.DisplayBubble(bubbleID, (int)PlayerDatas.Instance.baseData.PlayerID);
+
+        avatarCell.InitUI(AvatarHelper.GetAvatarModel((int)PlayerDatas.Instance.baseData.PlayerID,
+                                                PlayerDatas.Instance.baseData.face,
+                                                PlayerDatas.Instance.baseData.facePic));
+        avatarCell.button.SetListener(() =>
         {
-            ChatData data = ChatCenter.Instance.GetChatData(ChatManager.Instance.presentChatType, cell.index);
-            if (data == null)
-            {
-                return;
-            }
-            var chatUserData = data as ChatUeseData;
 
-            m_ChatBubble.DisplayContent(data.content);
+        });
 
-            //  TODO YYL
-            // int bubbleID = phantasmPavilionModel.GetNowChatBubbleID();
-            // m_ChatBubble.DisplayBubble(bubbleID);
-
-            // avatarCell.InitUI(AvatarHelper.GetMyAvatarModel());
-            // avatarCell.button.SetListener(() =>
-            // {
-            //     OnFunc(cell);
-            // });
-
-            m_PlayerName.text = chatUserData.name;
-            m_ChatTime.text = data.createTime.ToString("yyyy-MM-dd HH:mm");
-            if (chatUserData.vipLv > 0)
-            {
-                m_VipLv.text = "VIP";//string.Format("V{0}", chatUserData.vipLv);
-            }
-            else
-            {
-                m_VipLv.text = string.Empty;
-            }
+        title.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID);
+        if (manager.nowChatTab == ChatTab.World)
+        {
+            string serverName = ServerListCenter.Instance.GetServerName(UIHelper.GetServerIDByAccount(PlayerDatas.Instance.baseData.AccID));
+            m_PlayerName.text = Language.Get("Chat08", serverName, PlayerDatas.Instance.baseData.PlayerName);
         }
-
-        private void OnFunc(CellView cell)
+        else
         {
-            int index = cell.index;
-            ChatData _data = ChatCenter.Instance.GetChatData(ChatManager.Instance.presentChatType, index);
-            if (_data == null)
-            {
-                return;
-            }
-            ChatUeseData user = _data as ChatUeseData;
-            if (user.player == PlayerDatas.Instance.baseData.PlayerID)
-            {
-                return;
-            }
-            HrefAnalysis.Inst.ExcuteHrefEvent(string.Format("<a>showplayer={0}</a>", user.player));
-        }
-
-        public float GetHeight(string content, ArrayList list)
-        {
-            var minHeight = m_avatarRect.sizeDelta.y;
-            var chatHeight = m_ChatBubble.GetBubbleHeight(content, list) + Mathf.Abs(m_ChatBubble.transform.localPosition.y);
-            return (chatHeight > minHeight ? chatHeight : minHeight) + spacing;
+            int fmlv = PlayerDatas.Instance.fairyData.mine.FmLV;
+            m_PlayerName.text = Language.Get("Chat08", RichTextMsgReplaceConfig.GetRichReplace("FAMILY", fmlv), PlayerDatas.Instance.baseData.PlayerName);
         }
     }
+
+    public float GetHeight(string content, ArrayList list)
+    {
+        var minHeight = m_avatarRect.sizeDelta.y;
+        var chatHeight = m_ChatBubble.GetBubbleHeight(content, list) + Mathf.Abs(m_ChatBubble.transform.localPosition.y);
+        return (chatHeight > minHeight ? chatHeight : minHeight) + spacing;
+    }
+}
diff --git a/Main/System/Chat/ChatPlayerOtherCell.cs b/Main/System/Chat/ChatPlayerOtherCell.cs
index 51d6da2..318c586 100644
--- a/Main/System/Chat/ChatPlayerOtherCell.cs
+++ b/Main/System/Chat/ChatPlayerOtherCell.cs
@@ -1,81 +1,56 @@
 锘縰sing System.Collections;
 using UnityEngine;
 using UnityEngine.UI;
-using EnhancedUI.EnhancedScroller;
 
-    public class ChatPlayerOtherCell : ScrollerUI
+public class ChatPlayerOtherCell : MonoBehaviour
+{
+    [SerializeField] AvatarCell avatarCell;
+    [SerializeField] RectTransform m_avatarRect;
+    [SerializeField] OfficialTitleCell title;
+    [SerializeField] Text m_PlayerName;
+    [SerializeField] ChatBubbleBehaviour m_ChatBubble;
+    [SerializeField] float spacing = 5.0f;
+    ChatManager manager { get { return ChatManager.Instance; } }
+    public void Refresh(CellView cell)
     {
-        // [SerializeField] AvatarCell avatarCell;
-        [SerializeField] RectTransform m_avatarRect;
-        [SerializeField] Text m_VipLv;
-        [SerializeField] Text m_PlayerName;
-        [SerializeField] Text m_ChatTime;
-        [SerializeField] ChatBubbleBehaviour m_ChatBubble;
-        [SerializeField] float spacing = 5.0f;
-
-        // PhantasmPavilionModel phantasmPavilionModel { get { return ModelCenter.Instance.GetModel<PhantasmPavilionModel>(); } }
-        public override void Refresh(CellView cell)
+        if (!manager.TryGetChatData(ChatManager.Instance.nowChatChannel, cell.index, out TalkData data))
+            return;
+        avatarCell.InitUI(AvatarHelper.GetAvatarModel((int)data.PlayerID, (int)data.Face, (int)data.PlayerID, data.Job));
+        avatarCell.button.SetListener(() =>
         {
-            var data = ChatCenter.Instance.GetChatData(ChatManager.Instance.presentChatType, cell.index);
-            if (data == null)
-            {
-                return;
-            }
-            var chatUserData = data as ChatUeseData;
+
+        });
+        title.InitUI(data.RealmLV, (int)data.TitleID);
 
 
-            // AvatarModel avatarModel = AvatarHelper.GetOtherAvatarModel(chatUserData.face, chatUserData.facePic, chatUserData.job);
-            // avatarCell.InitUI(avatarModel);
-            // avatarCell.button.SetListener(() =>
-            // {
-            //     OnFunc(cell);
-            // });
 
-            m_PlayerName.text = chatUserData.name;
-            m_ChatTime.text = data.createTime.ToString("yyyy-MM-dd HH:mm");
-            if (chatUserData.vipLv > 0)
-            {
-                m_VipLv.text = "VIP";//string.Format("V{0}", chatUserData.vipLv);
-            }
-            else
-            {
-                m_VipLv.text = string.Empty;
-            }
-            m_ChatBubble.DisplayContent(data.content, true);
-            // int bubbleID = phantasmPavilionModel.GetNowOtherChatBubbleID(chatUserData.bubbleId);
-            // m_ChatBubble.DisplayBubble(bubbleID);
+        m_ChatBubble.DisplayContent(data.Content, true);
+
+        int bubbleID = ChatBubbleHelper.GetOtherChatBubbleID(data.Job, (int)data.BubbleBox);
+        m_ChatBubble.DisplayBubble(bubbleID, (int)data.PlayerID);
+
+        if (manager.nowChatTab == ChatTab.World)
+        {
+            string serverName = ServerListCenter.Instance.GetServerName((int)data.ServerID);
+            m_PlayerName.text = Language.Get("Chat08", serverName, data.Name);
         }
-
-        private void OnFunc(CellView cell)
+        else
         {
-            int index = cell.index;
-            ChatData _data = ChatCenter.Instance.GetChatData(ChatManager.Instance.presentChatType, index);
-            if (_data == null)
+            FairyMember fairyMember = PlayerDatas.Instance.fairyData.GetMember((int)data.PlayerID);
+            int fmlv = 0;
+            if (fairyMember != null)
             {
-                return;
+                fmlv = fairyMember.FmLV;
             }
-            ChatUeseData user = _data as ChatUeseData;
-            if (user.player == PlayerDatas.Instance.baseData.PlayerID)
-            {
-                return;
-            }
-            if (user.serverGroupId == 0 || user.serverGroupId == PlayerDatas.Instance.baseData.ServerGroupId)
-            {
-                // TODO YYL
-                // PlayerDetails.ShowPlayerDetails(user.player, null);
-            }
-            else
-            {
-                // TODO YYL
-                // PlayerDetails.ShowCrossServerChatPlayer(user);
-            }
-        }
-
-        public float GetHeight(string content, ArrayList list)
-        {
-            var minHeight = m_avatarRect.sizeDelta.y;
-            var chatHeight = m_ChatBubble.GetBubbleHeight(content, list) + Mathf.Abs(m_ChatBubble.transform.localPosition.y);
-            return (chatHeight > minHeight ? chatHeight : minHeight) + spacing;
+            m_PlayerName.text = Language.Get("Chat08", RichTextMsgReplaceConfig.GetRichReplace("FAMILY", fmlv), data.Name);
         }
     }
 
+    public float GetHeight(string content, ArrayList list)
+    {
+        var minHeight = m_avatarRect.sizeDelta.y;
+        var chatHeight = m_ChatBubble.GetBubbleHeight(content, list) + Mathf.Abs(m_ChatBubble.transform.localPosition.y);
+        return (chatHeight > minHeight ? chatHeight : minHeight) + spacing;
+    }
+}
+
diff --git a/Main/System/Chat/ChatRecently.cs b/Main/System/Chat/ChatRecently.cs
deleted file mode 100644
index 34221a8..0000000
--- a/Main/System/Chat/ChatRecently.cs
+++ /dev/null
@@ -1,108 +0,0 @@
-锘縰sing System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Linq;
-using UnityEngine;
-    public class ChatRecently : MonoBehaviour
-    {
-        [SerializeField] ScrollerController m_RecentlyControl;
-
-        // FriendsModel m_FriendModel;
-        // FriendsModel friendModel
-        // {
-        //     get
-        //     {
-        //         return m_FriendModel ?? (m_FriendModel = ModelCenter.Instance.GetModel<FriendsModel>());
-        //     }
-        // }
-
-        private void OnEnable()
-        {
-            UpdatePlayer();
-            DisplayRecently();
-            // friendModel.RefreshFriendCntEvent += RefreshFriendCntEvent;
-            // friendModel.RefreshFriendModel += DisplayRecently;
-        }
-
-        private void OnDisable()
-        {
-            // friendModel.RefreshFriendCntEvent -= RefreshFriendCntEvent;
-            // friendModel.RefreshFriendModel -= DisplayRecently;
-        }
-
-        private void DisplayRecently()
-        {
-            m_RecentlyControl.Refresh();
-            // var _dict = friendModel.GetFriendInfoDict((byte)GroupType.RecentContact);
-            // if (_dict != null)
-            // {
-            //     if (friendModel.tempFriendData != null && !_dict.ContainsKey(friendModel.tempFriendData.PlayerID))
-            //     {
-            //         m_RecentlyControl.AddCell(ScrollerDataType.Header, (int)friendModel.tempFriendData.PlayerID, OnClickFriend);
-            //     }
-            //     foreach (var _id in _dict.Keys)
-            //     {
-            //         m_RecentlyControl.AddCell(ScrollerDataType.Header, (int)_id, OnClickFriend);
-            //     }
-            // }
-            // else if (friendModel.tempFriendData != null)
-            // {
-            //     m_RecentlyControl.AddCell(ScrollerDataType.Header, (int)friendModel.tempFriendData.PlayerID, OnClickFriend);
-            // }
-            m_RecentlyControl.Restart();
-        }
-
-        private void OnClickFriend(CellView _cell)
-        {
-            // if(_cell.index!= ChatManager.Instance.PteChatID)
-            // {
-            //     ChatManager.Instance.PteChatID = _cell.index;
-            //     var _dict = friendModel.GetFriendInfoDict((byte)GroupType.RecentContact);
-            //     if (friendModel.tempFriendData != null
-            //         && ChatManager.Instance.PteChatID == friendModel.tempFriendData.PlayerID)
-            //     {
-            //         ChatManager.Instance.PteChatName = friendModel.tempFriendData.PlayerName;
-            //         LanguageVerify.toPlayerLevel = friendModel.tempFriendData.LV;
-            //     }
-            //     else
-            //     {
-            //         ChatManager.Instance.PteChatName = _dict != null && _dict.ContainsKey((uint)ChatManager.Instance.PteChatID) ?
-            //                         _dict[(uint)ChatManager.Instance.PteChatID].PlayerName : string.Empty;
-            //         LanguageVerify.toPlayerLevel = _dict != null && _dict.ContainsKey((uint)ChatManager.Instance.PteChatID) ?
-            //                         _dict[(uint)ChatManager.Instance.PteChatID].LV : 0;
-            //     }
-            //     ChatManager.Instance.SelectRecentlyChat(ChatManager.Instance.PteChatID);
-            //     m_RecentlyControl.m_Scorller.RefreshActiveCellViews();
-            // }
-        }
-
-        private void RefreshFriendCntEvent(/*GroupType _type, bool arg2*/)
-        {
-            // if (_type == GroupType.RecentContact)
-            // {
-            //     DisplayRecently();
-            // }
-        }
-
-        private void UpdatePlayer()
-        {
-            // TODO YYL
-            // if (friendModel.tempFriendData != null)
-            // {
-            //     ChatManager.Instance.PteChatID = (int)friendModel.tempFriendData.PlayerID;
-            //     ChatManager.Instance.PteChatName = friendModel.tempFriendData.PlayerName;
-            //     LanguageVerify.toPlayerLevel = friendModel.tempFriendData.LV;
-            //     ChatManager.Instance.SelectRecentlyChat(ChatManager.Instance.PteChatID);
-            //     return;
-            // }
-            // var _dict = friendModel.GetFriendInfoDict((byte)GroupType.RecentContact);
-            // if (_dict != null && _dict.Count > 0)
-            // {
-            //     ChatManager.Instance.PteChatID = (int)_dict.Keys.First();
-            //     ChatManager.Instance.PteChatName = _dict[(uint)ChatManager.Instance.PteChatID].PlayerName;
-            //     LanguageVerify.toPlayerLevel = _dict[(uint)ChatManager.Instance.PteChatID].LV;
-            //     ChatManager.Instance.SelectRecentlyChat(ChatManager.Instance.PteChatID);
-            // }
-        }
-    }
-
diff --git a/Main/System/Chat/ChatRecently.cs.meta b/Main/System/Chat/ChatRecently.cs.meta
deleted file mode 100644
index 5e461e3..0000000
--- a/Main/System/Chat/ChatRecently.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: b7daa7a18d7fb904ead12815d531a9df
-MonoImporter:
-  externalObjects: {}
-  serializedVersion: 2
-  defaultReferences: []
-  executionOrder: 0
-  icon: {instanceID: 0}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 
diff --git a/Main/System/Chat/ChatRecentlyCell.cs b/Main/System/Chat/ChatRecentlyCell.cs
deleted file mode 100644
index 5299288..0000000
--- a/Main/System/Chat/ChatRecentlyCell.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-锘縰sing System.Collections;
-using System.Collections.Generic;
-using UnityEngine;
-using UnityEngine.UI;
-
-
-
-public class ChatRecentlyCell : ScrollerUI
-{
-    [SerializeField] Image m_PlayerBG;
-    [SerializeField] Image m_Select;
-    [SerializeField] Text m_PlayerName;
-    [SerializeField] Text m_Lv;
-    [SerializeField] Image m_LvSign;
-    [SerializeField] Text m_LvText;
-    [SerializeField] Button m_DetailBtn;
-
-    public override void Refresh(CellView cell)
-    {
-        // TODO YYL
-        // var _playerId = cell.index;
-        // var _dict = friendModel.GetFriendInfoDict((byte)GroupType.RecentContact);
-        // FriendPlayer _friendPlayer = null;
-        // if (_dict != null && _dict.ContainsKey((uint)_playerId))
-        // {
-        //     _friendPlayer = _dict[(uint)_playerId];
-        // }
-        // else if (friendModel.tempFriendData != null && friendModel.tempFriendData.PlayerID == _playerId)
-        // {
-        //     _friendPlayer = friendModel.tempFriendData;
-        // }
-        // if (_friendPlayer == null)
-        // {
-        //     return;
-        // }
-        // m_Select.SetActive(_playerId == ChatCtrl.Inst.PteChatID);
-        // m_PlayerName.text = _friendPlayer.PlayerName;
-        // m_LvSign.SetActive(false);
-        // var _lv = _friendPlayer.LV ;
-        // m_LvText.text = (_lv > 0 ? _lv : _friendPlayer.LV).ToString();
-        // m_DetailBtn.onClick.RemoveAllListeners();
-        // m_DetailBtn.onClick.AddListener(() =>
-        // {
-        //     PlayerDetails.ShowPlayerDetails(_playerId, null);
-        // });
-        // SetOnline(_friendPlayer.OnlineType == 1);
-    }
-
-    private void SetOnline(bool _online)
-    {
-        m_PlayerBG.material = _online ? MaterialUtility.GetUIDefaultGraphicMaterial() : MaterialUtility.GetDefaultSpriteGrayMaterial();
-        m_LvSign.material = _online ? MaterialUtility.GetUIDefaultGraphicMaterial() : MaterialUtility.GetDefaultSpriteGrayMaterial();
-        m_Lv.color = _online ? UIHelper.GetUIColor(TextColType.NavyBrown) : UIHelper.GetUIColor(TextColType.White, true);
-        m_LvText.color = _online ? UIHelper.GetUIColor(TextColType.NavyBrown) : UIHelper.GetUIColor(TextColType.White, true);
-        m_PlayerName.color = _online ? UIHelper.GetUIColor(TextColType.NavyBrown) : UIHelper.GetUIColor(TextColType.White, true);
-    }
-}
-
diff --git a/Main/System/Chat/ChatRecentlyCell.cs.meta b/Main/System/Chat/ChatRecentlyCell.cs.meta
deleted file mode 100644
index 0f668dd..0000000
--- a/Main/System/Chat/ChatRecentlyCell.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 0f8061f41da2e504db0e4b0a742928df
-MonoImporter:
-  externalObjects: {}
-  serializedVersion: 2
-  defaultReferences: []
-  executionOrder: 0
-  icon: {instanceID: 0}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 
diff --git a/Main/System/Chat/ChatSendComponent.cs b/Main/System/Chat/ChatSendComponent.cs
deleted file mode 100644
index 970dc40..0000000
--- a/Main/System/Chat/ChatSendComponent.cs
+++ /dev/null
@@ -1,480 +0,0 @@
-锘縰sing System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Text.RegularExpressions;
-
-using UnityEngine;
-using UnityEngine.UI;
-using Cysharp.Threading.Tasks;
-
-    public class ChatSendComponent : MonoBehaviour
-    {
-        [SerializeField] Button m_SendBtn;
-        [SerializeField] InputField m_ChatInput;
-        [SerializeField] Button m_ExtentBtn;
-        // [SerializeField] VoiceRecorder m_VoiceRecorder;
-        [SerializeField] RichText m_ChatValueDisplay;
-        [SerializeField] Text m_Placeholder;
-        [SerializeField, Header("涓婄Щ楂樺害")] float m_UpHeight = 300.0f;
-
-        public Text placeholder { get { return m_Placeholder; } }
-        public Button sendBtn { get { return m_SendBtn; } }
-
-        // PhantasmPavilionModel phantasmPavilionModel { get { return ModelCenter.Instance.GetModel<PhantasmPavilionModel>(); } }
-        // VipModel vipModel { get { return ModelCenter.Instance.GetModel<VipModel>(); } }
-        // [NonSerialized] public UIBase parent;
-
-        private bool m_OnChating = false;
-
-        private void Awake()
-        {
-            m_SendBtn.onClick.AddListener(OnChatSend);
-            m_ExtentBtn.onClick.AddListener(OnExtent);
-            m_ChatInput.onValueChanged.AddListener(OnChatValueChange);
-        }
-
-        private void OnEnable()
-        {
-            // m_VoiceRecorder.voiceRecordSuccessEvent += OnVoiceRecordSuccessEvent;
-            FuncOpen.Instance.OnFuncStateChangeEvent += OnFuncStateChangeEvent;
-            ChatCenter.Instance.UpdateChatValueEvent += UpdateChatValueEvent;
-            ChatCenter.Instance.UpdateChatType += UpdateChatType;
-            m_ChatInput.characterLimit = ChatCenter.Instance.chatCharacterLimit;
-            // WindowCenter.Instance.windowAfterCloseEvent += WindowAfterCloseEvent;
-            // phantasmPavilionModel.SendChatAction += OnSendChatAction;
-            m_OnChating = false;
-        }
-
-        private void OnDisable()
-        {
-            // m_VoiceRecorder.voiceRecordSuccessEvent -= OnVoiceRecordSuccessEvent;
-            FuncOpen.Instance.OnFuncStateChangeEvent -= OnFuncStateChangeEvent;
-            ChatCenter.Instance.UpdateChatValueEvent -= UpdateChatValueEvent;
-            ChatCenter.Instance.UpdateChatType -= UpdateChatType;
-            // WindowCenter.Instance.windowAfterCloseEvent -= WindowAfterCloseEvent;
-            // phantasmPavilionModel.SendChatAction -= OnSendChatAction;
-        }
-
-        // private void WindowAfterCloseEvent(Window _window)
-        // {
-        //     if (_window is ChatExtentWin)
-        //     {
-        //         if (parent != null)
-        //         {
-        //             parent.transform.localPosition = parent.transform.localPosition.SetY(0);
-        //         }
-        //     }
-        // }
-
-        private void LateUpdate()
-        {
-        }
-
-        private void UpdateChatType()
-        {
-            m_Placeholder.text = ChatManager.Instance.presentChatType == ChatInfoType.Trumpet ? Language.Get("L1012") : Language.Get("L1111");
-        }
-
-        bool ChangeBranch()
-        {
-            if (m_ChatInput.text.StartsWith("#@#BrancH"))
-            {
-                if (m_ChatInput.text.Split(' ')[1] == "c")
-                {
-                    //鍒犻櫎璁板綍
-                    LocalSave.DeleteKey("#@#BrancH");
-                    ScrollTip.ShowTip("娓呯悊鍒嗘敮璁剧疆");
-                }
-                else
-                {
-                    //鍒囨崲鍒嗘敮
-                    LocalSave.SetString("#@#BrancH", m_ChatInput.text.Split(' ')[1]);
-                    ScrollTip.ShowTip("鍒嗘敮璁剧疆瀹屾瘯");
-                }
-                return true;
-            }
-            return false;
-        }
-
-        private void OnChatSend()
-        {
-            if (ChangeBranch()) return;
-
-            if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.Chat))
-            {
-                FuncOpen.Instance.ProcessorFuncErrorTip((int)FuncOpenEnum.Chat);
-                return;
-            }
-
-            // TODO YYL
-            // if (vipModel.realRecharge < ChatCenter.Instance.talkRechargeLimmit || 
-            //     PlayerDatas.Instance.baseData.LV < ChatCenter.Instance.talkLevelLimmit)
-            // {
-            //     SysNotifyMgr.Instance.ShowTip("mdtqInfo1", ChatCenter.Instance.talkRechargeLimmit, ChatCenter.Instance.talkLevelLimmit);
-            //     return;
-            // }
-
-            if (ChatManager.Instance.presentChatType == ChatInfoType.CrossServer)
-            {
-                if (!FuncOpen.Instance.IsFuncOpen(162))
-                {
-                    SysNotifyMgr.Instance.ShowTip("CrossServerHint");
-                    return;
-                }
-            }
-            ChatExtraData? info = null;
-            SinglePack singlePack = PackManager.Instance.GetSinglePack(PackType.Item);
-            if (ChatManager.Instance.presentChatType == ChatInfoType.Trumpet)
-            {
-                if (ChatCenter.Instance.IsChatBanned || ChatCenter.Instance.clientBanned)
-                {
-                    return;
-                }
-
-                var count = singlePack.GetCountById(ChatCenter.Instance.bugleItem);
-                if (count < 1)
-                {
-                    ConfirmCancel.ShowPopConfirm(Language.Get("Mail101"), Language.Get("NoTrumpet"), () =>
-                    {
-                        // TODO YYL
-                        // WindowJumpMgr.Instance.WindowJumpTo(JumpUIType.StoreFunc2);
-                    });
-                    return;
-                }
-
-                var items = singlePack.GetItemsById(ChatCenter.Instance.bugleItem);
-                info = new ChatExtraData() { infoint1 = items[0].gridIndex };
-            }
-            if (m_ChatInput.text.Length < 1)
-            {
-                return;
-            }
-            if (m_OnChating)
-            {
-                return;
-            }
-            if (CheckChatCD())
-            {
-                SysNotifyMgr.Instance.ShowTip("OnChatCD");
-                return;
-            }
-            if (!ChatCenter.Instance.clientBanned)
-            {
-                CheckRepeatContent(m_ChatInput.text);
-                CheckMaliceChat(m_ChatInput.text);
-            }
-            m_OnChating = true;
-            string msg = m_ChatInput.text;
-
-            string tmpMsg = ImgAnalysis.ReplaceFace(msg, out int faceCount);
-
-            if (DirtyWordConfig.IsDirtWord(tmpMsg))
-            {
-                tmpMsg = DirtyWordConfig.IsDirtWord(tmpMsg, '*');
-                tmpMsg = tmpMsg.Replace("*", "");
-                m_ChatInput.text = tmpMsg;
-                SysNotifyMgr.Instance.ShowTip("DirtyWordWarn");
-                m_OnChating = false;
-                return;
-            }
-
-            ChatManager.Instance.SendChatInfo(ChatManager.Instance.presentChatType, msg, info, false);
-            StartCoroutine(Co_CoolDowmChat());
-
-            // TODO YYL
-            // ModelCenter.Instance.GetModel<FirstTimeRechargeModel>().AskFirstRechargeMore(msg);
-        }
-
-        private void OnChatSend(string msg)
-        {
-            if (ChangeBranch()) return;
-
-            if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.Chat))
-            {
-                FuncOpen.Instance.ProcessorFuncErrorTip((int)FuncOpenEnum.Chat);
-                return;
-            }
-            if (ChatManager.Instance.presentChatType == ChatInfoType.CrossServer)
-            {
-                if (!FuncOpen.Instance.IsFuncOpen(162))
-                {
-                    SysNotifyMgr.Instance.ShowTip("CrossServerHint");
-                    return;
-                }
-            }
-            ChatExtraData? info = null;
-            SinglePack singlePack = PackManager.Instance.GetSinglePack(PackType.Item);
-            if (ChatManager.Instance.presentChatType == ChatInfoType.Trumpet)
-            {
-                if (ChatCenter.Instance.IsChatBanned || ChatCenter.Instance.clientBanned)
-                {
-                    return;
-                }
-
-                var count = singlePack.GetCountById(ChatCenter.Instance.bugleItem);
-                if (count < 1)
-                {
-                    ConfirmCancel.ShowPopConfirm(Language.Get("Mail101"), Language.Get("NoTrumpet"), () =>
-                    {
-                        // TODO YYL
-                        // WindowJumpMgr.Instance.WindowJumpTo(JumpUIType.StoreFunc2);
-                    });
-                    return;
-                }
-
-                var items = singlePack.GetItemsById(ChatCenter.Instance.bugleItem);
-                info = new ChatExtraData() { infoint1 = items[0].gridIndex };
-            }
-            if (msg.Length < 1)
-            {
-                return;
-            }
-            if (m_OnChating)
-            {
-                return;
-            }
-            if (CheckChatCD())
-            {
-                SysNotifyMgr.Instance.ShowTip("OnChatCD");
-                return;
-            }
-            if (!ChatCenter.Instance.clientBanned)
-            {
-                CheckRepeatContent(msg);
-                CheckMaliceChat(msg);
-            }
-            m_OnChating = true;
-            ChatManager.Instance.SendChatInfo(ChatManager.Instance.presentChatType, msg, info, false);
-            StartCoroutine(Co_CoolDowmChat());
-        }
-
-        IEnumerator Co_CoolDowmChat()
-        {
-            yield return new WaitForSeconds(1.5f);
-            // yield return WaitingForSecondConst.WaitMS1500;
-            m_OnChating = false;
-        }
-
-        private void OnChatValueChange(string _msg)
-        {
-            string _chat = Regex.Replace(_msg, @"\p{Cs}|&", "");
-            if (!_chat.Equals(_msg))
-            {
-                m_ChatInput.text = _chat;
-                ChatCenter.Instance.chatInputLength = m_ChatInput.text.Length;
-            }
-            if (_msg.Equals(string.Empty))
-            {
-                ChatCenter.Instance.recentlyChat = null;
-            }
-            m_ChatValueDisplay.text = _chat;
-            MatchCollection matchArray = HrefAnalysis.EquipRegex.Matches(_chat);
-            if (matchArray.Count == 0)
-            {
-                ChatManager.Instance.itemPlaceList.Clear();
-                ChatCenter.Instance.recentlyChat = null;
-                return;
-            }
-            if (ChatCenter.Instance.recentlyChat == null)
-            {
-                if (ChatManager.Instance.itemPlaceList.Count == matchArray.Count)
-                {
-                    return;
-                }
-            }
-            if (ChatCenter.Instance.recentlyChat != null)
-            {
-                var _recentlyChat = ChatCenter.Instance.recentlyChat;
-                for (int i = 0, m = 0; i < _recentlyChat.itemIndexs.Count; i++)
-                {
-                    if (m < matchArray.Count)
-                    {
-                        Match match = matchArray[m];
-                        if (_recentlyChat.itemNames[_recentlyChat.itemIndexs[i]] != match.Groups[1].Value)
-                        {
-                            _recentlyChat.itemIndexs.RemoveAt(i);
-                            i--;
-                        }
-                        else
-                        {
-                            m++;
-                        }
-                    }
-                }
-                return;
-            }
-            for (int i = 0, m = 0; i < ChatManager.Instance.itemPlaceList.Count; i++)
-            {
-                if (m < matchArray.Count)
-                {
-                    Match match = matchArray[m];
-                    ItemModel itemModel = ChatManager.Instance.itemPlaceList[i];
-                    ItemConfig cfg = ItemConfig.Get((int)itemModel.itemId);
-                    if (cfg.ItemName != match.Groups[1].Value)
-                    {
-                        ChatManager.Instance.itemPlaceList.RemoveAt(i);
-                        i--;
-                    }
-                    else
-                    {
-                        m++;
-                    }
-                }
-            }
-        }
-
-        private void UpdateChatValueEvent(string _msg, bool _add, bool _force)
-        {
-            if (_add)
-            {
-                m_ChatInput.text += _msg;
-                ChatCenter.Instance.chatInputLength = m_ChatInput.text.Length;
-            }
-            else
-            {
-                m_ChatInput.text = _msg;
-                ChatCenter.Instance.chatInputLength = m_ChatInput.text.Length;
-            }
-        }
-
-        private void OnExtent()
-        {
-            // if (!WindowCenter.Instance.IsOpen<ChatExtentWin>())
-            // {
-            //     WindowCenter.Instance.Open<ChatExtentWin>(true);
-            //     if (parent != null)
-            //     {
-            //         parent.transform.localPosition = parent.transform.localPosition.SetY(m_UpHeight);
-            //     }
-            // }
-            // else
-            // {
-            //     WindowCenter.Instance.Close<ChatExtentWin>();
-            //     if (parent != null)
-            //     {
-            //         parent.transform.localPosition = parent.transform.localPosition.SetY(0);
-            //     }
-            // }
-        }
-
-        // private void OnVoiceRecordSuccessEvent(int _instance, float _length)
-        // {
-        //     var _type = ChatManager.Instance.presentChatType;
-        //     ChatCenter.Instance.SetVoice(_instance, _type, _length, _type == ChatInfoType.Friend ? ChatManager.Instance.PteChatID : 0);
-        // }
-
-        private void OnFuncStateChangeEvent(int _id)
-        {
-            if (_id == (int)FuncOpenEnum.Chat)
-            {
-            }
-        }
-
-        #region 鎭舵剰鍙戣█
-        static string repeatChatContent = string.Empty;
-        static int repeatChatCount = 0;
-        static DateTime repeatTime = DateTime.Now;
-        private void CheckRepeatContent(string _content)
-        {
-            if (ChatManager.Instance.IsAssitChat(_content, true) == 0 && repeatChatContent.Equals(_content)
-                && (TimeUtility.ServerNow - repeatTime).TotalSeconds < ChatCenter.Instance.banCheckSecond)
-            {
-                repeatChatCount++;
-                if (repeatChatCount >= ChatCenter.Instance.repeatCountLimit)
-                {
-                    Co_ClientBan().Forget();
-                }
-            }
-            else
-            {
-                repeatChatContent = _content;
-                repeatChatCount = 1;
-                repeatTime = TimeUtility.ServerNow;
-            }
-        }
-
-        static int maliceChatCount = 0;
-        static int maliceRecordCount = 0;
-        static DateTime maliceChatTime = DateTime.Now;
-        private void CheckMaliceChat(string _content)
-        {
-            if ((TimeUtility.ServerNow - maliceChatTime).TotalSeconds < ChatCenter.Instance.banCheckSecond
-                && maliceChatCount > 0 && maliceRecordCount < ChatCenter.Instance.maliceCheckCount)
-            {
-                maliceRecordCount++;
-                if (ChatManager.GetUTF8InfoLen(_content) == 1)
-                {
-                    maliceChatCount++;
-                }
-                if (maliceChatCount >= ChatCenter.Instance.maliceLimitCount)
-                {
-                    Co_ClientBan().Forget();
-                }
-            }
-            else
-            {
-                if (ChatManager.GetUTF8InfoLen(_content) == 1)
-                {
-                    maliceChatCount = 1;
-                    maliceRecordCount = 1;
-                    maliceChatTime = TimeUtility.ServerNow;
-                }
-                else
-                {
-                    maliceChatCount = 0;
-                    maliceRecordCount = 0;
-                }
-            }
-        }
-
-        async UniTask Co_ClientBan()
-        {
-            await UniTask.Yield();
-            ChatCenter.Instance.ChatClientBan();
-        }
-        #endregion
-
-        #region 鑱婂ぉCD
-        private DateTime chatCdTime = DateTime.Now;
-        private int chatCdCount = 0;
-        private bool chatBusy = false;
-        public bool CheckChatCD()
-        {
-            if (chatBusy && (DateTime.Now - chatCdTime).TotalSeconds < 10)
-            {
-                return true;
-            }
-            else if (chatBusy)
-            {
-                chatBusy = false;
-                chatCdCount = 0;
-            }
-            if ((DateTime.Now - chatCdTime).TotalSeconds < 2)
-            {
-                chatCdCount++;
-            }
-            else
-            {
-                chatCdCount = 1;
-            }
-            if (chatCdCount > 5)
-            {
-                chatBusy = true;
-                return true;
-            }
-            chatCdTime = DateTime.Now;
-            return false;
-        }
-        #endregion
-
-        private void OnSendChatAction(string msg)
-        {
-            OnChatSend(msg);
-            // WindowCenter.Instance.Close<ChatExtentWin>();
-            // if (parent != null)
-            // {
-            //     parent.transform.localPosition = parent.transform.localPosition.SetY(0);
-            // }
-        }
-    }
-
diff --git a/Main/System/Chat/ChatSendComponent.cs.meta b/Main/System/Chat/ChatSendComponent.cs.meta
deleted file mode 100644
index 305aad4..0000000
--- a/Main/System/Chat/ChatSendComponent.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 58d9b99b8e7b0214188aa4ce9bb60c51
-MonoImporter:
-  externalObjects: {}
-  serializedVersion: 2
-  defaultReferences: []
-  executionOrder: 0
-  icon: {instanceID: 0}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 
diff --git a/Main/System/Chat/ChatSettingButton.cs b/Main/System/Chat/ChatSettingButton.cs
new file mode 100644
index 0000000..315e205
--- /dev/null
+++ b/Main/System/Chat/ChatSettingButton.cs
@@ -0,0 +1,27 @@
+锘縰sing UnityEngine;
+
+public class ChatSettingButton : MonoBehaviour
+{
+    [SerializeField] ButtonEx btnSelect;
+    [SerializeField] ImageEx imgSelect;
+    private ChatChannel channelType;
+    private bool isAvtive;
+    ChatManager manager { get { return ChatManager.Instance; } }
+    void Awake()
+    {
+        btnSelect.SetListener(() =>
+        {
+            isAvtive = !isAvtive;
+            manager.SetBulletSetting(channelType, isAvtive);
+            imgSelect.SetActive(isAvtive);
+        });
+    }
+
+    public void SetChannelType(ChatChannel type)
+    {
+        channelType = type;
+        isAvtive = manager.GetBulletSetting(channelType);
+        imgSelect.SetActive(isAvtive);
+    }
+}
+
diff --git a/Main/System/Chat/ChatFriendTipCell.cs.meta b/Main/System/Chat/ChatSettingButton.cs.meta
similarity index 83%
copy from Main/System/Chat/ChatFriendTipCell.cs.meta
copy to Main/System/Chat/ChatSettingButton.cs.meta
index 2e709c7..609d098 100644
--- a/Main/System/Chat/ChatFriendTipCell.cs.meta
+++ b/Main/System/Chat/ChatSettingButton.cs.meta
@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 68376cb82e4739943aecb4dbbd81a757
+guid: 0f526b90dcff2ff4db9163d67839e2f1
 MonoImporter:
   externalObjects: {}
   serializedVersion: 2
diff --git a/Main/System/Chat/ChatSysCell.cs b/Main/System/Chat/ChatSysCell.cs
new file mode 100644
index 0000000..42e97b7
--- /dev/null
+++ b/Main/System/Chat/ChatSysCell.cs
@@ -0,0 +1,32 @@
+锘縰sing System.Collections;
+using UnityEngine;
+
+public class ChatSysCell : MonoBehaviour
+{
+    [SerializeField] ChatBubbleBehaviour m_ChatBubble;
+    [SerializeField] RichText chatText;
+    ChatManager manager { get { return ChatManager.Instance; } }
+    public void Refresh(CellView cell)
+    {
+        if (!manager.TryGetChatData(manager.nowChatChannel, cell.index, out TalkData data))
+            return;
+        if (data.InfoList != null)
+        {
+            chatText.SetExtenalData(data.InfoList);
+        }
+        m_ChatBubble.DisplaySysBubble(manager.sysBubbleID, manager.sysBubbleColor);
+        m_ChatBubble.DisplayContent(data.Content, true);
+    }
+
+    public float GetHeight(string content, ArrayList list)
+    {
+        var chatHeight = m_ChatBubble.GetBubbleHeight(content, list);
+        if (string.IsNullOrEmpty(content))
+        {
+            chatHeight = 0;
+        }
+        //Debug.Log($"GetHeight {chatHeight} chatHeight {chatHeight} GetBubbleHeight {m_ChatBubble.GetBubbleHeight(content, list)} Abs {Mathf.Abs(m_ChatBubble.transform.localPosition.y)}");
+        return chatHeight;
+    }
+}
+
diff --git a/Main/System/Chat/ChatTrailCell.cs.meta b/Main/System/Chat/ChatSysCell.cs.meta
similarity index 100%
rename from Main/System/Chat/ChatTrailCell.cs.meta
rename to Main/System/Chat/ChatSysCell.cs.meta
diff --git a/Main/System/Chat/ChatTabCell.cs b/Main/System/Chat/ChatTabCell.cs
new file mode 100644
index 0000000..bf611c7
--- /dev/null
+++ b/Main/System/Chat/ChatTabCell.cs
@@ -0,0 +1,46 @@
+锘縰sing UnityEngine;
+using UnityEngine.UI;
+
+public class ChatTabCell : MonoBehaviour
+{
+    [SerializeField] ImageEx imgSelectBg;
+    [SerializeField] ImageEx imgSelect;
+    [SerializeField] ImageEx imgUnSelect;
+    [SerializeField] TextEx txtTitle;
+    [SerializeField] Button btnSelect;
+    [SerializeField] Color selectedColor;
+    [SerializeField] Color unSelectColor;
+
+    ChatManager manager { get { return ChatManager.Instance; } }
+    public void Display(int index, CellView cellView)
+    {
+        int tab = cellView.info.Value.infoInt1;
+        if (!manager.IsValidChatTab(tab))
+            return;
+        ChatTab chatTab = (ChatTab)tab;
+
+        bool isSelect = manager.IsSelectChatTab(chatTab);
+        imgSelectBg.SetActive(isSelect);
+        imgSelect.SetActive(isSelect);
+        imgUnSelect.SetActive(!isSelect);
+
+        imgSelect.SetSprite(manager.GetChatTabSelectIcon(chatTab, true));
+        imgUnSelect.SetSprite(manager.GetChatTabSelectIcon(chatTab, false));
+
+        imgSelectBg.SetNativeSize();
+        imgSelect.SetNativeSize();
+        imgUnSelect.SetNativeSize();
+
+        txtTitle.text = manager.GetChatTabName(chatTab);
+        txtTitle.color = isSelect ? selectedColor : unSelectColor;
+
+        btnSelect.SetListener(() =>
+        {
+            if (!manager.IsTabOpen(chatTab, true))
+                return;
+            manager.nowChatTab = chatTab;
+        });
+    }
+
+}
+
diff --git a/Main/System/Chat/ChatFriendTipCell.cs.meta b/Main/System/Chat/ChatTabCell.cs.meta
similarity index 83%
copy from Main/System/Chat/ChatFriendTipCell.cs.meta
copy to Main/System/Chat/ChatTabCell.cs.meta
index 2e709c7..500a5c4 100644
--- a/Main/System/Chat/ChatFriendTipCell.cs.meta
+++ b/Main/System/Chat/ChatTabCell.cs.meta
@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 68376cb82e4739943aecb4dbbd81a757
+guid: 3c621c88da6d81042baee40698e785ce
 MonoImporter:
   externalObjects: {}
   serializedVersion: 2
diff --git a/Main/System/Chat/ChatTrailCell.cs b/Main/System/Chat/ChatTrailCell.cs
deleted file mode 100644
index 7431452..0000000
--- a/Main/System/Chat/ChatTrailCell.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-锘縰sing System.Collections;
-using System.Collections.Generic;
-using UnityEngine;
-using UnityEngine.UI;
-
-
-public class ChatTrailCell : ScrollerUI
-{
-    [SerializeField] Image chatIcon;
-    [SerializeField] RichText chatText;
-
-    public override void Refresh(CellView cell)
-    {
-        ChatData _data = ChatCenter.Instance.GetChatData(ChatManager.Instance.presentChatType, cell.index);
-        if (_data == null)
-        {
-            return;
-        }
-        if (_data.infoList != null)
-        {
-            chatText.SetExtenalData(_data.infoList);
-        }
-        chatIcon.SetActive(true);
-        if (_data.type == ChatInfoType.Invite)
-        {
-            chatIcon.SetSprite("ChatIcon_Invite");
-        }
-        else if (_data.type == ChatInfoType.System)
-        {
-            chatIcon.SetSprite("ChatIcon_System");
-        }
-        else if (_data.type == ChatInfoType.Friend)
-        {
-            chatIcon.SetSprite("ChatIcon_System");
-        }
-        else
-        {
-            chatIcon.SetActive(false);
-        }
-        chatText.text = _data.type == ChatInfoType.Friend ? _data.content.Replace(ChatManager.KILL_IDENTIFY, string.Empty) : _data.content;
-    }
-}
-
diff --git a/Main/System/Chat/ChatWin.cs b/Main/System/Chat/ChatWin.cs
index dd55b49..88441ed 100644
--- a/Main/System/Chat/ChatWin.cs
+++ b/Main/System/Chat/ChatWin.cs
@@ -1,279 +1,514 @@
-锘�//--------------------------------------------------------
-//    [Author]:           鐜╀釜娓告垙
-//    [  Date ]:           Monday, April 09, 2018
-//--------------------------------------------------------
-
-using System;
+锘縰sing System;
 using System.Collections;
 using System.Collections.Generic;
-
 using UnityEngine;
 using UnityEngine.UI;
 
+public class ChatWin : UIBase
+{
+    [SerializeField, Header("閿佸畾褰撳墠鍖哄煙姣斾緥"), Range(0, 1)] float m_Percent = 0.3f;
+    [SerializeField] ButtonEx btnSetting;
+    [SerializeField] ButtonEx btnClose;
 
-    public class ChatWin : UIBase
+    [SerializeField] ScrollerController scrChatTab;
+    [SerializeField] ChatPlayerMineCell m_ChatMineCell;
+    [SerializeField] ChatPlayerOtherCell m_ChatOtherCell;
+    [SerializeField] ChatSysCell m_ChatSysCell;
+
+    [SerializeField] Transform transInput;
+    [SerializeField] InputField inputChat;
+    [SerializeField] ButtonEx btnSendChat;
+    [SerializeField] ImageEx imgSendChat;
+    [SerializeField] TextEx txtSendChat;
+    [SerializeField] ScrollerController scrWorld;
+    [SerializeField] ScrollerController scrGuild;
+
+    private int unreadMsgCount = 0;
+    [SerializeField] ButtonEx btnNewMsgTip;
+    [SerializeField] TextEx txtNewMsgTip;
+
+    [SerializeField, Header("鑱婂ぉ寮瑰箷璁剧疆")] Transform transSettings;
+    [SerializeField] ClickScreenOtherSpace clickScreenOtherSpace;
+    bool isSettingOpen = false;
+    [SerializeField] ChatSettingButton btnWorldSetting;
+    [SerializeField] ChatSettingButton btnGuildSetting;
+    ChatManager manager { get { return ChatManager.Instance; } }
+
+    protected override void InitComponent()
     {
-        [SerializeField] Button m_CloseBtn;
-        [SerializeField] Text m_ChatTip;
-        [SerializeField] ChatSendComponent m_ChatSend;
-        [SerializeField] ScrollerController m_ChannelControl;
-        [SerializeField] ChatContentBehaviour m_ChatContent;
-        [SerializeField] ChatRecently m_ChatRecently;
-        [SerializeField] Button m_ChannelBtn;
-        [SerializeField] Text m_ChannelInfo;
-
-
-        protected override void InitComponent()
+        base.InitComponent();
+        btnClose.SetListener(CloseWindow);
+        btnSendChat.SetListener(() =>
         {
-            m_CloseBtn.onClick.AddListener(OnClose);
-            m_ChannelBtn.onClick.AddListener(OnChannelBtn);
-        }
-
-        protected override void OnPreOpen()
-        {
-            if (!IsSatisfyShowChannel(ChatManager.Instance.presentChatType))
+            // 濡傛灉鍦ㄨ亰澶╄緭鍏ョ晫闈㈡棤杈撳叆鏂囧瓧鐐瑰嚮鍙戦�侊紝鍒欏叧闂亰澶╄緭鍏ョ晫闈�
+            if (string.IsNullOrEmpty(inputChat.text))
             {
-                ChatManager.Instance.presentChatType = ChatInfoType.System;
+                CloseWindow();
+                return;
             }
 
-            // m_ChatSend.parent = this;
-            ChatManager.Instance.lockUpdate = false;
-            ChatManager.Instance.OnPteChatChangeEvent += OnPteChatChangeEvent;
-            ChatManager.Instance.OpenPteChatEvent += OpenPteChatEvent;
-            DisplayChannel();
-            OnChatTypeChange();
-            ChatCenter.Instance.UpdateChatContentPos();
-        }
-
-        protected override void OnOpen()
-        {
-            AchievementRandomWord();
-            if (ChatManager.Instance.openFromDaily)
+            if (!manager.CheckChatLimit(inputChat.text, out int errorCode))
             {
-                AssitRandomChat();
-                ChatManager.Instance.needCheckAssitChat = true;
+                manager.ShowChatErrorTip(errorCode);
+                return;
             }
-            else if (ChatManager.Instance.openFromGem)
+            manager.SendChatInfo(manager.nowChatChannel, inputChat.text);
+            manager.AddChatChannelSendTime(manager.nowChatChannel, TimeUtility.AllSeconds);
+            inputChat.text = string.Empty;
+            UpdateSendButton();
+        });
+        btnNewMsgTip.SetListener(() =>
+        {
+            if (manager.nowChatChannel == ChatChannel.World)
             {
-                string chat = Language.Get("ThanksGift" + UnityEngine.Random.Range(1, 4));
-                if (chat != string.Empty)
-                {
-                    ChatCenter.Instance.ChangeChatValue(chat, false, true);
-                }
+                RefreshChat(manager.nowChatChannel, scrWorld);
+                ScrollerJump(scrWorld, ChatChannel.World);
             }
-            else if (ChatManager.Instance.openFromFairyTask)
+            else if (manager.nowChatChannel == ChatChannel.Guild)
             {
-                TaskRandomChat();
+                RefreshChat(manager.nowChatChannel, scrGuild);
+                ScrollerJump(scrGuild, ChatChannel.Guild);
             }
-            ChatManager.Instance.openFromDaily = false;
-            ChatManager.Instance.openFromGem = false;
-            ChatManager.Instance.openFromFairyTask = false;
-        }
-
-        protected override void OnPreClose()
+            ClearUnreadMsg();
+        });
+        btnSetting.SetListener(() =>
         {
-            ChatManager.Instance.OnPteChatChangeEvent -= OnPteChatChangeEvent;
-            ChatManager.Instance.OpenPteChatEvent -= OpenPteChatEvent;
-            ChatManager.Instance.openFromDaily = false;
-            ChatManager.Instance.openFromGem = false;
-            ChatManager.Instance.needCheckAssitChat = false;
-            ChatManager.Instance.openFromFairyTask = false;
-            //ChatCenter.Instance.ChangeChatValue(string.Empty, false, true);
-            //ChatManager.Instance.itemPlaceList.Clear();
-        }
+            isSettingOpen = !isSettingOpen;
+            transSettings.SetActive(isSettingOpen);
+        });
 
-        protected override void OnClose()
-        {
-        }
+    }
 
-        private void OpenPteChatEvent()
-        {
-            OnChannelSelect(ChatInfoType.Friend);
-        }
+    // 娓呯悊鏈娑堟伅鐘舵��
+    private void ClearUnreadMsg()
+    {
+        unreadMsgCount = 0;
+        btnNewMsgTip.SetActive(false);
+    }
 
-        private void DisplayChannel()
-        {
-            m_ChannelControl.Refresh();
-            for (int i = 0; i < ChatCenter.Instance.chatChannels.Count; i++)
-            {
-                if (IsSatisfyShowChannel(ChatCenter.Instance.chatChannels[i]))
-                {
-                    m_ChannelControl.AddCell(ScrollerDataType.Normal, (int)ChatCenter.Instance.chatChannels[i], OnChannelSelect);
-                }
-            }
-            m_ChannelControl.Restart();
+    // 鏇存柊鏈娑堟伅UI
+    private void UpdateUnreadMsgUI()
+    {
+        btnNewMsgTip.SetActive(unreadMsgCount > 0);
+        txtNewMsgTip.text = Language.Get("Chat10", unreadMsgCount);
+    }
 
-            m_ChannelControl.JumpIndex(Math.Min((int)ChatManager.Instance.presentChatType, m_ChannelControl.GetNumberOfCells(m_ChannelControl.m_Scorller) - 1));
+    protected override void OnPreOpen()
+    {
+        base.OnPreOpen();
+        manager.OnChatTabChangeEvent += OnChatTabChange;
+        manager.OnUpdateTalkEvent += OnUpdateTalkEvent;
+        manager.OnUpdateTalkCacheListEvent += OnUpdateTalkCacheList;
 
-        }
+        scrChatTab.OnRefreshCell += OnRefreshChatTabCell;
+        scrWorld.OnGetDynamicSize += OnGetWorldChatDynamicSize;
+        scrWorld.OnRefreshCell += OnRefreshWorldCell;
+        scrWorld.mScrollRect.onValueChanged.AddListener(OnWorldScrollValChange);
+        scrGuild.OnGetDynamicSize += OnGetWorldChatDynamicSize;
+        scrGuild.OnRefreshCell += OnRefreshGuildCell;
+        scrGuild.mScrollRect.onValueChanged.AddListener(OnGuildScrollValChange);
 
-        private bool IsSatisfyShowChannel(ChatInfoType channel)
-        {
+        clickScreenOtherSpace.AddListener(OnClickScreenOtherSpace);
+        GlobalTimeEvent.Instance.secondEvent += OnSecondEvent;
 
-            return true;
-        }
-
-        private void OnPteChatChangeEvent()
-        {
-            if (ChatManager.Instance.presentChatType == ChatInfoType.Friend)
-            {
-                OnChatTypeChange();
-            }
-        }
-
-        private void OnChatTypeChange()
-        {
-            m_ChannelBtn.SetActive(false);
-            m_ChannelInfo.SetActive(false);
-            m_ChatSend.placeholder.text= Language.Get("L1111");
-            m_CloseBtn.SetActive(ChatManager.Instance.presentChatType != ChatInfoType.Friend);
-            switch (ChatManager.Instance.presentChatType)
-            {
-                case ChatInfoType.Trumpet:
-                    m_ChatRecently.SetActive(false);
-                    m_ChatTip.SetActive(false);
-                    m_ChatSend.SetActive(true);
-                    m_ChatSend.placeholder.text = Language.Get("L1012");
-                    break;
-                case ChatInfoType.Invite:
-                case ChatInfoType.System:
-                    m_ChatRecently.SetActive(false);
-                    m_ChatTip.text = Language.Get("L1109");
-                    m_ChatTip.SetActive(true);
-                    m_ChatSend.SetActive(false);
-                    break;
-                case ChatInfoType.World:
-                case ChatInfoType.Area:
-                case ChatInfoType.CrossServer:
-                case ChatInfoType.default1:
-                    m_ChatRecently.SetActive(false);
-                    m_ChatTip.SetActive(false);
-                    m_ChatSend.SetActive(true);
-                    break;
-                case ChatInfoType.Team:
-                    // TODO YYL
-                    // m_ChatRecently.SetActive(false);
-                    // var _team = ModelCenter.Instance.GetModel<TeamModel>().myTeam;
-                    // m_ChatSend.SetActive(_team.teamId > 0);
-                    // m_ChatTip.SetActive(_team.teamId <= 0);
-                    // m_ChatTip.text = Language.Get("L1110");
-                    break;
-                case ChatInfoType.Fairy:
-                    // TODO YYL
-                    // m_ChatRecently.SetActive(false);
-                    // m_ChannelBtn.SetActive(!PlayerDatas.Instance.fairyData.HasFairy);
-                    // m_ChannelInfo.SetActive(!PlayerDatas.Instance.fairyData.HasFairy);
-                    // m_ChatTip.SetActive(!PlayerDatas.Instance.fairyData.HasFairy);
-                    // m_ChatSend.SetActive(PlayerDatas.Instance.fairyData.HasFairy);
-                    // if (!PlayerDatas.Instance.fairyData.HasFairy)
-                    // {
-                    //     m_ChatTip.text = Language.Get("L1011");
-                    // }
-                    break;
-                case ChatInfoType.Friend:
-                    m_ChatSend.SetActive(true);
-                    m_ChatTip.SetActive(false);
-                    if (!m_ChatRecently.gameObject.activeSelf)
-                    {
-                        m_ChatRecently.SetActive(true);
-                    }
-                    break;
-            }
-            m_ChatContent.chatType = ChatManager.Instance.presentChatType;
-            ChatManager.Instance.ViewChat(ChatManager.Instance.presentChatType);
-        }
-
-        private void OnChannelSelect(CellView _cell)
-        {
-            if ((ChatInfoType)_cell.index == ChatInfoType.CrossServer)
-            {
-                if (!FuncOpen.Instance.IsFuncOpen(162))
-                {
-                    SysNotifyMgr.Instance.ShowTip("CrossServerHint");
-                    return;
-                }
-            }
-            OnChannelSelect((ChatInfoType)_cell.index);
-        }
-
-        private void OnChannelSelect(ChatInfoType _type)
-        {
-            ChatManager.Instance.presentChatType = _type;
-            m_ChannelControl.m_Scorller.RefreshActiveCellViews();
-            if (_type == ChatInfoType.Friend)
-            {
-                ChatManager.Instance.lockUpdate = true;
-            }
-            else
-            {
-                ChatManager.Instance.lockUpdate = false;
-            }
-            OnChatTypeChange();
-            ChatCenter.Instance.UpdateChatContentPos();
-        }
-
-        private void OnChannelBtn()
-        {
-            switch (ChatManager.Instance.presentChatType)
-            {
-                case ChatInfoType.Fairy:
-                    {
-                        int limit = FuncOpenLVConfig.Get((int)FuncOpenEnum.Guild).LimitLV;
-                        if (PlayerDatas.Instance.baseData.LV < limit)
-                        {
-                            ServerTipDetails.DisplayNormalTip(Language.Get("L1136", limit));
-                            return;
-                        }
-                        CloseWindow();
-                        // TODO YYL
-                        // WindowJumpMgr.Instance.WindowJumpTo(JumpUIType.UnionFunc3);
-                    }
-                    break;
-            }
-        }
-
-        private void AchievementRandomWord()
-        {
-            // TODO YYL
-            // if (AchievementGoto.achievementType != AchievementGoto.RandomFairyChat
-            //     && AchievementGoto.achievementType != AchievementGoto.RandomWorldChat)
-            // {
-            //     return;
-            // }
-            // AchievementGoto.achievementType = 0;
-            // if (AchievementGoto.achievementType == AchievementGoto.RandomFairyChat && !PlayerDatas.Instance.fairyData.HasFairy)
-            // {
-            //     return;
-            // }
-            // if (ChatManager.Instance.achievementRandoms.ContainsKey(ChatManager.Instance.presentChatType))
-            // {
-            //     var _list = ChatManager.Instance.achievementRandoms[ChatManager.Instance.presentChatType];
-            //     int _index = UnityEngine.Random.Range(0, _list.Count);
-            //     ChatCenter.Instance.ChangeChatValue(Language.Get(_list[_index]), false, true);
-            // }
-            // var _effect = AchievementGuideEffectPool.Require(1);
-            // _effect.transform.SetParentEx(m_ChatSend.sendBtn.transform, Vector3.zero, Vector3.zero, Vector3.one);
-        }
-
-        private void AssitRandomChat()
-        {
-            ChatCenter.Instance.ChangeChatValue(ChatManager.Instance.GetAssitRandomChat(ChatManager.Instance.presentChatType), false, true);
-        }
-
-        private void TaskRandomChat()
-        {
-            ChatCenter.Instance.ChangeChatValue(ChatManager.Instance.GetTaskRandomChat(ChatManager.Instance.presentChatType), false, true);
-        }
-
-        private void GemFlauntChat()
-        {
-            // TODO YYL
-            // ChatCenter.Instance.ChangeChatValue(ChatManager.Instance.GetGemFlauntChat(), false, true);
-            // var _effect = AchievementGuideEffectPool.Require(1);
-            // _effect.transform.SetParentEx(m_ChatSend.sendBtn.transform, Vector3.zero, Vector3.zero, Vector3.one);
-        }
-
+        isSettingOpen = false;
+        transSettings.SetActive(isSettingOpen);
+        btnWorldSetting.SetChannelType(ChatChannel.World);
+        btnGuildSetting.SetChannelType(ChatChannel.Guild);
+        inputChat.characterLimit = ChatManager.Instance.characterLimit;
+        CreaterAll(manager.nowChatTab);
     }
 
 
 
+    protected override void OnPreClose()
+    {
+        base.OnPreClose();
+        manager.OnChatTabChangeEvent -= OnChatTabChange;
+        manager.OnUpdateTalkEvent -= OnUpdateTalkEvent;
+        manager.OnUpdateTalkCacheListEvent -= OnUpdateTalkCacheList;
+
+        scrChatTab.OnRefreshCell -= OnRefreshChatTabCell;
+        scrWorld.OnGetDynamicSize -= OnGetWorldChatDynamicSize;
+        scrWorld.OnRefreshCell -= OnRefreshWorldCell;
+        scrWorld.mScrollRect.onValueChanged.RemoveListener(OnWorldScrollValChange);
+        scrGuild.OnGetDynamicSize -= OnGetGuildChatDynamicSize;
+        scrGuild.OnRefreshCell -= OnRefreshGuildCell;
+        scrGuild.mScrollRect.onValueChanged.RemoveListener(OnGuildScrollValChange);
+        GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent;
+        clickScreenOtherSpace.RemoveAllListeners();
+    }
+
+    private void OnRefreshGuildCell(ScrollerDataType type, CellView cell)
+    {
+        OnRefreshCell(type, cell);
+    }
+
+    private void OnRefreshWorldCell(ScrollerDataType type, CellView cell)
+    {
+        OnRefreshCell(type, cell);
+    }
+    private void OnRefreshCell(ScrollerDataType type, CellView cell)
+    {
+        if (type == ScrollerDataType.Header)
+        {
+            var _cell = cell.GetComponent<ChatPlayerMineCell>();
+            _cell?.Refresh(cell);
+        }
+        else if (type == ScrollerDataType.Normal)
+        {
+            var _cell = cell.GetComponent<ChatPlayerOtherCell>();
+            _cell?.Refresh(cell);
+        }
+        else if (type == ScrollerDataType.Tail)
+        {
+            var _cell = cell.GetComponent<ChatSysCell>();
+            _cell?.Refresh(cell);
+        }
+        else if (type == ScrollerDataType.Extra1)
+        {
+            var _cell = cell.GetComponent<ChatDateCell>();
+            _cell?.Refresh(cell);
+        }
+    }
+
+    private void OnSecondEvent()
+    {
+        UpdateSendButton();
+    }
+
+    private void OnClickScreenOtherSpace()
+    {
+        isSettingOpen = !isSettingOpen;
+        transSettings.SetActive(isSettingOpen);
+    }
+
+    private bool m_isJumpArea;
+    public bool isJumpArea
+    {
+        get { return m_isJumpArea; }
+        set
+        {
+            if (m_isJumpArea == value)
+                return;
+            m_isJumpArea = value;
+
+            // isJumpArea = true (鐢ㄦ埛鍦ㄥ簳閮�)锛氬紑鍚攣瀹氬簳閮�
+            if (value)
+            {
+                if (scrWorld.lockType != EnhanceLockType.LockVerticalBottom)
+                    scrWorld.lockType = EnhanceLockType.LockVerticalBottom;
+
+                // 濡傛灉鍥炲埌搴曢儴锛岀洿鎺ユ竻闆舵秷鎭�
+                ClearUnreadMsg();
+            }
+            // isJumpArea = false (鐢ㄦ埛鐪嬪巻鍙�)锛氫繚鎸佽瑙変綅缃�
+            else
+            {
+                if (scrWorld.lockType != EnhanceLockType.KeepVertical)
+                    scrWorld.lockType = EnhanceLockType.KeepVertical;
+            }
+        }
+    }
+
+    private void OnWorldScrollValChange(Vector2 _pos)
+    {
+        OnScrollValChange(scrWorld, _pos);
+    }
+
+    private void OnGuildScrollValChange(Vector2 _pos)
+    {
+        OnScrollValChange(scrGuild, _pos);
+    }
+
+    private void OnScrollValChange(ScrollerController scorller, Vector2 _pos)
+    {
+        if (scorller.m_Scorller._ScrollSize <= 0)
+            return;
+
+        float _value = m_Percent / scorller.m_Scorller._ScrollSize * scorller.m_Scorller.ScrollRectSize;
+        isJumpArea = _pos.y <= _value;
+
+        // 妫�鏌ユ粴鍔ㄤ綅缃槸鍚﹁鐩栦簡鏂版秷鎭�
+        if (unreadMsgCount <= 0)
+            return;
+        int totalCount = scorller.GetNumberOfCells(scorller.m_Scorller);
+        int thresholdIndex = totalCount - unreadMsgCount;
+
+        // 鑾峰彇褰撳墠瑙嗙獥鏈�搴曢儴鏄剧ず鐨� Item 绱㈠紩
+        int currentBottomIndex = scorller.m_Scorller.EndDataIndex;
+        // 濡傛灉褰撳墠鐪嬪埌鐨勫簳閮ㄧ储寮� 瓒呰繃浜� 鏂版秷鎭殑璧峰绾�(鍑�1鏄负浜嗗閿�)
+        if (currentBottomIndex >= thresholdIndex - 1)
+        {
+            ClearUnreadMsg();
+        }
+    }
+
+    private void OnChatTabChange(ChatTab entrance)
+    {
+        CreaterAll(entrance);
+    }
+
+    private void OnUpdateTalkEvent(ChatChannel type, TalkData data)
+    {
+        RefreshAll(type, playerId: data.PlayerID);
+    }
+
+    private void OnUpdateTalkCacheList()
+    {
+        RefreshAll(manager.nowChatChannel);
+    }
+
+    private void CreaterAll(ChatTab chatTab)
+    {
+        if (chatTab == ChatTab.World)
+        {
+            manager.nowChatChannel = ChatChannel.World;
+        }
+        else if (chatTab == ChatTab.Guild)
+        {
+            manager.nowChatChannel = ChatChannel.Guild;
+        }
+
+        UpdateSendButton();
+        // 鎵撳紑鐣岄潰鏃堕粯璁ゅ埌搴曢儴锛屾棤鏈
+        isJumpArea = true;
+        scrWorld.lockType = EnhanceLockType.LockVerticalBottom; // 鍒濆閿佸畾搴曢儴
+        scrWorld.SetActive(chatTab == ChatTab.World);
+
+        scrGuild.lockType = EnhanceLockType.LockVerticalBottom; // 鍒濆閿佸畾搴曢儴
+        scrGuild.SetActive(chatTab == ChatTab.Guild);
+
+        transInput.SetActive(chatTab == ChatTab.World || chatTab == ChatTab.Guild);
+
+        CreateChatTabScroller();
+
+        switch (chatTab)
+        {
+            case ChatTab.World:
+                manager.nowChatChannel = ChatChannel.World;
+                CreateScroller(scrWorld, ChatChannel.World);
+                ScrollerJump(scrWorld, ChatChannel.World);
+                ClearUnreadMsg();
+                break;
+            case ChatTab.Guild:
+                manager.nowChatChannel = ChatChannel.Guild;
+                CreateScroller(scrGuild, ChatChannel.Guild);
+                ScrollerJump(scrGuild, ChatChannel.Guild);
+                ClearUnreadMsg();
+                break;
+        }
+    }
+
+    float KeepArea(ScrollerController scroller)
+    {
+        if (scroller.GetNumberOfCells(scroller.m_Scorller) >= manager.maxTalkCount)
+        {
+            float totalRemovedSize = 0f;
+            for (int i = 0; i < manager.deleteTalkCount; i++)
+            {
+                float cellSize = scroller.GetCellSize(i);
+                totalRemovedSize += cellSize + scroller.m_Scorller.spacing;
+            }
+            return totalRemovedSize;
+        }
+        return 0;
+    }
+
+    private void RefreshAll(ChatChannel type, uint playerId = 0)
+    {
+        scrChatTab.m_Scorller.RefreshActiveCellViews();
+        if (type == ChatChannel.World)
+        {
+            RefreshChat(type, scrWorld, playerId);
+        }
+        else if (type == ChatChannel.Guild)
+        {
+            RefreshChat(type, scrGuild, playerId);
+        }
+
+    }
+
+    private void RefreshChat(ChatChannel type, ScrollerController scroller, uint playerId = 0)
+    {
+        if (!manager.TryGetTalkData(type, out List<TalkData> datas) || datas == null)
+            return;
+        int numberOfCells = scroller.GetNumberOfCells(scroller.m_Scorller);
+        if (numberOfCells < manager.maxTalkCount)
+        {
+            for (int i = numberOfCells; i < datas.Count; i++)
+            {
+
+                TalkData data = datas[i];
+                ScrollerDataType scrollerDataType = GetCellType(data);
+                scroller.AddCell(scrollerDataType, i);
+                int talkDataType = manager.GetTalkDataType(data);
+                float height = GetHeight(talkDataType, data.Content, data.InfoList);
+                scroller.m_Scorller.AddHeight(true, height);
+                //Debug.Log($"ChatWin AddCell i {i} AddHeight {height}");
+            }
+        }
+        else
+        {
+            scroller.m_Scorller.RefreshActiveCellViews();
+        }
+
+        if (type == ChatChannel.World && manager.nowChatTab != ChatTab.World)
+            return;
+        if (type == ChatChannel.Guild && manager.nowChatTab != ChatTab.Guild)
+            return;
+        // 1. 鑷繁鍙戦�佺殑娑堟伅 -> 寮哄埗璺宠浆鍒板簳閮� + 娓呴浂
+        if (playerId == PlayerDatas.Instance.PlayerId)
+        {
+            isJumpArea = true;
+            scroller.lockType = EnhanceLockType.LockVerticalBottom;
+            ScrollerJump(scroller, type);
+            ClearUnreadMsg(); // 鑷繁鍙戠殑娑堟伅涓嶇敤鎻愮ず
+        }
+        // 2. 鍒汉鍙戞秷鎭� & 褰撳墠鍦ㄥ簳閮� -> 鑷姩璺熼殢 + 娓呴浂
+        else if (isJumpArea)
+        {
+            scroller.lockType = EnhanceLockType.LockVerticalBottom;
+            ScrollerJump(scroller, type);
+            ClearUnreadMsg(); // 鍦ㄥ簳閮ㄧ湅鐫�涓嶇敤鎻愮ず
+        }
+        // 3. 鍒汉鍙戞秷鎭� & 褰撳墠鍦ㄧ湅鍘嗗彶 -> 淇濇寔浣嶇疆 + 澧炲姞鏈璁℃暟
+        else
+        {
+            scroller.lockType = EnhanceLockType.KeepVertical;
+            float offset = KeepArea(scroller);
+            if (Math.Abs(offset) > 0.001f)
+            {
+                ScrollerJump(scroller, offset);
+            }
+
+            if (type == manager.nowChatChannel)
+            {
+                unreadMsgCount++;
+                UpdateUnreadMsgUI();
+            }
+
+            // 鐗规畩鎯呭喌锛氬鏋滄湭璇绘暟閲忓法澶э紙瓒呰繃浜嗘�绘樉绀烘暟閲忥級,璇存槑鏁翠釜鍒楄〃閮借鍒锋柊浜�,鐩存帴娑堥浂
+            if (unreadMsgCount >= scrWorld.GetNumberOfCells(scrWorld.m_Scorller))
+            {
+                ClearUnreadMsg();
+            }
+        }
+    }
+    private bool OnGetWorldChatDynamicSize(ScrollerDataType _type, int _index, out float height)
+    {
+        return OnGetChatDynamicSize(_type, _index, out height);
+    }
+
+    private bool OnGetGuildChatDynamicSize(ScrollerDataType _type, int _index, out float height)
+    {
+        return OnGetChatDynamicSize(_type, _index, out height);
+    }
+
+    private bool OnGetChatDynamicSize(ScrollerDataType _type, int _index, out float height)
+    {
+        height = 0;
+        if (!manager.TryGetChatData(manager.nowChatChannel, _index, out TalkData data) || data == null)
+            return false;
+        switch (_type)
+        {
+            case ScrollerDataType.Header:
+                height = m_ChatMineCell.GetHeight(data.Content, data.InfoList);
+                return true;
+            case ScrollerDataType.Normal:
+                height = m_ChatOtherCell.GetHeight(data.Content, data.InfoList);
+                return true;
+            case ScrollerDataType.Tail:
+                height = m_ChatSysCell.GetHeight(data.Content, data.InfoList);
+                return true;
+            case ScrollerDataType.Extra1:
+                height = 30;
+                return true;
+        }
+        return true;
+    }
+    private void OnRefreshChatTabCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell.GetComponent<ChatTabCell>();
+        _cell?.Display(cell.index, cell);
+    }
+
+    private void CreateChatTabScroller()
+    {
+        scrChatTab.Refresh();
+        for (int i = 0; i < manager.tabShowList.Count; i++)
+        {
+            CellInfo cellInfo = new CellInfo();
+            cellInfo.infoInt1 = (int)manager.tabShowList[i];
+            scrChatTab.AddCell(ScrollerDataType.Header, i, cellInfo);
+        }
+        scrChatTab.Restart();
+    }
+
+    private void CreateScroller(ScrollerController scroller, ChatChannel type)
+    {
+        scroller.Refresh();
+        if (manager.TryGetTalkData(type, out List<TalkData> datas))
+        {
+            for (int i = 0; i < datas.Count; i++)
+            {
+                TalkData data = datas[i];
+                ScrollerDataType scrollerDataType = GetCellType(data);
+                scroller.AddCell(scrollerDataType, i);
+            }
+        }
+        scroller.Restart();
+    }
+
+    private void ScrollerJump(ScrollerController scroller, ChatChannel type)
+    {
+        scroller.lockType = EnhanceLockType.LockVerticalBottom;
+        scroller.ResetScrollPos();
+        int jumpIndex = manager.GetJumpIndex(type);
+        scroller.JumpIndex(jumpIndex);
+        //Debug.Log($"ChatWin JumpIndex {jumpIndex}");
+        isJumpArea = true;
+    }
+
+
+    private void ScrollerJump(ScrollerController scroller, float _offset)
+    {
+        scroller.JumpIndex(-_offset, 0, EnhancedUI.EnhancedScroller.EnhancedScroller.TweenType.immediate);
+    }
+    // 0-绯荤粺 1-鏃ユ湡 2-鑷繁 3-鍏朵粬鐜╁
+    private ScrollerDataType GetCellType(TalkData data)
+    {
+        int type = manager.GetTalkDataType(data);
+        if (type == 0)
+            return ScrollerDataType.Tail;
+        else if (type == 1)
+            return ScrollerDataType.Extra1;
+        else if (type == 2)
+            return ScrollerDataType.Header;
+        else
+            return ScrollerDataType.Normal;
+    }
+    public float GetHeight(int type, string content, ArrayList list)
+    {
+        switch (type)
+        {
+            case 0:
+                return m_ChatSysCell.GetHeight(content, list);
+            case 1:
+                return 30;
+            case 2:
+                return m_ChatMineCell.GetHeight(content, list);
+            case 3:
+                return m_ChatOtherCell.GetHeight(content, list);
+        }
+        return 0;
+    }
+    private void UpdateSendButton()
+    {
+        bool isCanSend = manager.IsCanSend(manager.nowChatChannel, out int remainingSeconds);
+        btnSendChat.interactable = isCanSend;
+        imgSendChat.gray = !isCanSend;
+        txtSendChat.text = isCanSend ? Language.Get("Chat02") : Language.Get("Chat14", remainingSeconds);
+        txtSendChat.colorType = isCanSend ? TextColType.NavyBrown : TextColType.LightWhite;
+    }
+}
\ No newline at end of file
diff --git a/Main/System/Chat/LocalChatHistory.cs b/Main/System/Chat/LocalChatHistory.cs
deleted file mode 100644
index 6d87173..0000000
--- a/Main/System/Chat/LocalChatHistory.cs
+++ /dev/null
@@ -1,324 +0,0 @@
-锘縰sing System.Collections;
-using System.Collections.Generic;
-using System.Text;
-using UnityEngine;
-using System;
-using System.IO;
-
-    
-    public class LocalChatHistory
-    {
-        public static Dictionary<ChatInfoType, List<string>> chatHistory = new Dictionary<ChatInfoType, List<string>>();
-
-        const string fileName = "ChatHistory";
-
-        public static int localSaveCount = 50;
-        public static int localChatKeepHour = 12;
-
-        static StringBuilder sb = new StringBuilder();
-
-        public static void Save()
-        {
-            if (!ExistAnyLocalChatHistory())
-            {
-                return;
-            }
-            var playerId = PlayerDatas.Instance.baseData.PlayerID;
-            var path = StringUtility.Contact(ResourcesPath.Instance.ExternalStorePath, fileName, "_", playerId, ".log");
-            using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write))
-            {
-                using (StreamWriter sw = new StreamWriter(fs, Encoding.UTF8))
-                {
-                    foreach (var type in chatHistory.Keys)
-                    {
-                        var list = chatHistory[type];
-                        if (list.Count > 0)
-                        {
-                            sw.WriteLine(StringUtility.Contact("channel:", (int)type));
-                            for (int i = 0; i < list.Count; i++)
-                            {
-                                sw.WriteLine(list[i]);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        static bool ExistAnyLocalChatHistory()
-        {
-            foreach (var list in chatHistory.Values)
-            {
-                if (list.Count > 0)
-                {
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        public static void Save<T>(T chat) where T : ChatUeseData
-        {
-            if (null == chat)
-            {
-                return;
-            }
-            switch (chat.type)
-            {
-                //case ChatInfoType.World:
-                case ChatInfoType.CrossServer:
-                case ChatInfoType.Area:
-                case ChatInfoType.Trumpet:
-                //case ChatInfoType.Fairy:
-                case ChatInfoType.Friend:
-                    if (chat.IsSound && string.IsNullOrEmpty(chat.content))
-                    {
-                        return;
-                    }
-                    var jsonString = ChatToString(chat);
-                    if (!string.IsNullOrEmpty(jsonString))
-                    {
-                        List<string> list;
-                        if (!chatHistory.TryGetValue(chat.type, out list))
-                        {
-                            list = new List<string>();
-                            chatHistory.Add(chat.type, list);
-                        }
-                        if (list.Count >= localSaveCount)
-                        {
-                            list.RemoveAt(0);
-                        }
-                        list.Add(jsonString);
-                    }
-                    break;
-            }
-            Save();
-        }
-
-        static void Save(ChatInfoType type, string line)
-        {
-            if (!string.IsNullOrEmpty(line))
-            {
-                List<string> list;
-                if (!chatHistory.TryGetValue(type, out list))
-                {
-                    list = new List<string>();
-                    chatHistory.Add(type, list);
-                }
-                if (list.Count >= localSaveCount)
-                {
-                    list.RemoveAt(0);
-                }
-                list.Add(line);
-            }
-        }
-
-        public static string ChatToString(ChatUeseData chat)
-        {
-            switch (chat.type)
-            {
-                //case ChatInfoType.World:
-                case ChatInfoType.Area:
-                case ChatInfoType.CrossServer:
-                case ChatInfoType.Team:
-                //case ChatInfoType.Fairy:
-                    {
-                        LocalChat localChat = new LocalChat();
-                        localChat.type = chat.type;
-                        localChat.player = chat.player;
-                        localChat.name = chat.name;
-                        localChat.extra = chat.extra;
-                        localChat.content = chat.content;
-                        localChat.time = chat.createTime;
-                        return LitJson.JsonMapper.ToJson(localChat);
-                    }
-                // case ChatInfoType.Trumpet:
-                //     {
-                //         var chatTrumpet = chat as ChatTrumpetData;
-                //         LocalTrumpetChat localChat = new LocalTrumpetChat();
-                //         localChat.player = chat.player;
-                //         localChat.name = chat.name;
-                //         localChat.extra = chat.extra;
-                //         localChat.content = chat.content;
-                //         localChat.speakType = chatTrumpet.speakType;
-                //         localChat.accId = chatTrumpet.accId;
-                //         localChat.time = chat.createTime;
-                //         return LitJson.JsonMapper.ToJson(localChat);
-                //     }
-                case ChatInfoType.Friend:
-                    {
-                        var chatFriend = chat as ChatFriendData;
-                        LocalFriendChat localChat = new LocalFriendChat();
-                        localChat.player = chat.player;
-                        localChat.name = chat.name;
-                        localChat.extra = chat.extra;
-                        localChat.toName = chatFriend.toName;
-                        localChat.toPlayer = chatFriend.toPlayer;
-                        localChat.talkType = chatFriend.talkType;
-                        localChat.content = chat.content;
-                        localChat.time = chat.createTime;
-                        return LitJson.JsonMapper.ToJson(localChat);
-                    }
-            }
-            return string.Empty;
-        }
-
-        public static void Read()
-        {
-            Clear();
-            var playerId = PlayerDatas.Instance.baseData.PlayerID;
-            var path = StringUtility.Contact(ResourcesPath.Instance.ExternalStorePath, fileName, "_", playerId, ".log");
-            if (!File.Exists(path))
-            {
-                return;
-            }
-            using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read))
-            {
-                using (StreamReader sr = new StreamReader(fs, Encoding.UTF8))
-                {
-                    ChatInfoType type = ChatInfoType.World;
-                    while (!sr.EndOfStream)
-                    {
-                        try
-                        {
-                            var line = sr.ReadLine();
-                            if (line.StartsWith("channel"))
-                            {
-                                type = (ChatInfoType)int.Parse(line.Split(':')[1]);
-                                continue;
-                            }
-                            if (type == ChatInfoType.Fairy)
-                            {
-                                if (PlayerDatas.Instance.baseData.FamilyId == 0)
-                                {
-                                    continue;
-                                }
-                            }
-                            ChatData chat = null;
-                            switch (type)
-                            {
-                                //case ChatInfoType.World:
-                                case ChatInfoType.Area:
-                                case ChatInfoType.CrossServer:
-                                case ChatInfoType.Team:
-                                    //case ChatInfoType.Fairy:
-                                    {
-                                        LocalChat localChat = LitJson.JsonMapper.ToObject<LocalChat>(line);
-                                        var ts = DateTime.Now - localChat.time;
-                                        if (ts.TotalHours >= localChatKeepHour)
-                                        {
-                                            continue;
-                                        }
-                                        if (type == ChatInfoType.World)
-                                        {
-                                            chat = new ChatWorldData(localChat.content, localChat.player, localChat.name, localChat.extra);
-                                        }
-                                        else if (type == ChatInfoType.Area)
-                                        {
-                                            chat = new ChatAreaData(localChat.content, localChat.player, localChat.name, localChat.extra);
-                                        }
-                                        else if (type == ChatInfoType.Team)
-                                        {
-                                            chat = new ChatTeamData(localChat.content, localChat.player, localChat.name, localChat.extra);
-                                        }
-                                        else if (type == ChatInfoType.Fairy)
-                                        {
-                                            chat = new ChatFamilyData(localChat.content, localChat.player, localChat.name, localChat.extra);
-                                        }
-                                        else if (type == ChatInfoType.CrossServer)
-                                        {
-                                            chat = new ChatCrossServerData(localChat.content, localChat.player, localChat.name, localChat.extra);
-                                        }
-                                        chat.createTime = localChat.time;
-                                    }
-                                    break;
-                                // case ChatInfoType.Trumpet:
-                                //     {
-                                //         LocalTrumpetChat localChat = LitJson.JsonMapper.ToObject<LocalTrumpetChat>(line);
-                                //         var ts = DateTime.Now - localChat.time;
-                                //         if (ts.TotalHours >= localChatKeepHour)
-                                //         {
-                                //             continue;
-                                //         }
-                                //         chat = new ChatTrumpetData(localChat.content, localChat.player, localChat.name,
-                                //             localChat.extra, localChat.speakType, localChat.accId);
-                                //         chat.createTime = localChat.time;
-                                //     }
-                                //     break;
-                                case ChatInfoType.Friend:
-                                    {
-                                        LocalFriendChat localChat = LitJson.JsonMapper.ToObject<LocalFriendChat>(line);
-                                        var ts = DateTime.Now - localChat.time;
-                                        if (ts.TotalHours >= localChatKeepHour)
-                                        {
-                                            continue;
-                                        }
-                                        chat = new ChatFriendData(localChat.content, localChat.player, localChat.name,
-                                            localChat.extra, localChat.toName, localChat.talkType, (uint)localChat.toPlayer);
-                                        chat.createTime = localChat.time;
-                                    }
-                                    break;
-                            }
-                            if (chat != null)
-                            {
-                                ChatManager.Instance.KeepLocalChat(chat);
-                            }
-                            Save(type, line);
-                        }
-                        catch (Exception e)
-                        {
-                            Debug.Log(e.Message);
-                            continue;
-                        }
-                    }
-                }
-            }
-        }
-
-        public static void Clear(ChatInfoType type)
-        {
-            if (chatHistory.ContainsKey(type))
-            {
-                chatHistory.Remove(type);
-                Save();
-            }
-        }
-
-        public static void Clear()
-        {
-            chatHistory.Clear();
-        }
-
-        public struct LocalChat
-        {
-            public ChatInfoType type;
-            public DateTime time;
-            public int player;
-            public string name;
-            public string extra;
-            public string content;
-        }
-
-        public struct LocalFriendChat
-        {
-            public DateTime time;
-            public int player;
-            public string name;
-            public string extra;
-            public string content;
-            public string toName;
-            public byte talkType;
-            public int toPlayer;
-        }
-
-        public struct LocalTrumpetChat
-        {
-            public DateTime time;
-            public int player;
-            public string name;
-            public string extra;
-            public string content;
-            public byte speakType;
-            public string accId;
-        }
-    }
\ No newline at end of file
diff --git a/Main/System/Chat/LocalChatHistory.cs.meta b/Main/System/Chat/LocalChatHistory.cs.meta
deleted file mode 100644
index 5e0fdcd..0000000
--- a/Main/System/Chat/LocalChatHistory.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 2be021001cf2964428f72448aa2c536d
-MonoImporter:
-  externalObjects: {}
-  serializedVersion: 2
-  defaultReferences: []
-  executionOrder: 0
-  icon: {instanceID: 0}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 
diff --git a/Main/System/Guild/GuildBaseWin.cs b/Main/System/Guild/GuildBaseWin.cs
index a7d6c73..d45e089 100644
--- a/Main/System/Guild/GuildBaseWin.cs
+++ b/Main/System/Guild/GuildBaseWin.cs
@@ -3,6 +3,7 @@
 using System.Collections.Generic;
 using Cysharp.Threading.Tasks;
 using DG.Tweening;
+using System.Text;
 using UnityEngine;
 using UnityEngine.UI;
 
@@ -20,8 +21,9 @@
     [SerializeField] Text guildMemberCountText;
     [SerializeField] Button rankBtn;
     [SerializeField] Button storeBtn;
-
-
+    [SerializeField] RichText talkInfoText;
+    [SerializeField] Button talkBtn;
+    [SerializeField] Button talkBtn1;
     [SerializeField] Button requestBtn;
 
 
@@ -56,6 +58,8 @@
             UIManager.Instance.OpenWindow<StoreBaseWin>();
         });
         InitHawker();
+        talkBtn.AddListener(OnClickTalkButton);
+        talkBtn1.AddListener(OnClickTalkButton);
     }
 
 
@@ -65,7 +69,8 @@
             return;
         GlobalTimeEvent.Instance.secondEvent += OnSecondEvent;
         GlobalTimeEvent.Instance.fiveSecondEvent += OnFiveSecondEvent;
-
+        ChatManager.Instance.OnUpdateTalkEvent += OnUpdateTalkEvent;
+        PlayerDatas.Instance.fairyData.OnRefreshFairyInfo += OnRefreshFairyInfo;
         Display();
     }
 
@@ -73,13 +78,27 @@
     {
         GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent;
         GlobalTimeEvent.Instance.fiveSecondEvent -= OnFiveSecondEvent;
+        ChatManager.Instance.OnUpdateTalkEvent -= OnUpdateTalkEvent;
+        PlayerDatas.Instance.fairyData.OnRefreshFairyInfo -= OnRefreshFairyInfo;
     }
 
+    void OnRefreshFairyInfo()
+    {
+        ShowGuildInfo();
+    }
+
+    private void OnUpdateTalkEvent(ChatChannel channel, TalkData data)
+    {
+        if (channel != ChatChannel.Guild)
+            return;
+        ShowTalkInfo();
+    }
 
     void Display()
     {
         ShowGuildInfo();
         ShowHawkerTime();
+        ShowTalkInfo();
     }
 
     void OnSecondEvent()
@@ -124,7 +143,7 @@
             if (modelPlay)
                 HawkerMove(true);
         }
-        
+
 
     }
 
@@ -159,8 +178,8 @@
             FuncNPCManager.Instance.isHawkerStandBy = isShow;
         };
     }
-    
-    
+
+
 
 
     //NPC瀵硅瘽鐩稿叧
@@ -190,4 +209,60 @@
         var npc = funcNPCs[index].GetModel();
         npc.PlayAnimation("idle", true);
     }
+
+    public void OnClickTalkButton()
+    {
+        ChatManager.Instance.nowChatTab = ChatTab.Guild;
+        ChatManager.Instance.nowChatChannel = ChatChannel.Guild;
+        UIManager.Instance.OpenWindow<ChatWin>();
+    }
+
+    public string GetGuildChatAreaContent(TalkData talkData)
+    {
+        int type = ChatManager.Instance.GetTalkDataType(talkData);
+        if (type == 0)
+        {
+            return Language.Get("L1100", Language.Get("Chat13"), talkData.Content);
+        }
+        else if (type == 1)
+        {
+            return Language.Get("L1100", Language.Get("Chat13"), talkData.Content);
+        }
+        else
+        {
+            return Language.Get("L1100", talkData.Name, talkData.Content);
+        }
+    }
+
+    public Color32 GetGuildChatAreaColor(TalkData talkData)
+    {
+        int type = ChatManager.Instance.GetTalkDataType(talkData);
+        if (type == 2)
+        {
+            return ChatManager.Instance.areaMyColor;
+        }
+        else
+        {
+            return ChatManager.Instance.areaOtherColor;
+        }
+    }
+
+    void ShowTalkInfo()
+    {
+        if (!ChatManager.Instance.TryGetTalkData(ChatChannel.Guild, out List<TalkData> datas) || datas.IsNullOrEmpty())
+        {
+            talkInfoText.text = string.Empty;
+            return;
+        }
+
+        StringBuilder stringBuilder = new StringBuilder();
+        int startIndex = Mathf.Max(datas.Count - 2, 0);
+        for (int i = startIndex; i < datas.Count; i++)
+        {
+            TalkData data = datas[i];
+            stringBuilder.Append(UIHelper.AppendColor(GetGuildChatAreaColor(data), GetGuildChatAreaContent(data)));
+            stringBuilder.AppendLine();
+        }
+        talkInfoText.text = stringBuilder.ToString();
+    }
 }
\ No newline at end of file
diff --git a/Main/System/Guild/GuildBossManager.cs b/Main/System/Guild/GuildBossManager.cs
index 72b8fd7..107246f 100644
--- a/Main/System/Guild/GuildBossManager.cs
+++ b/Main/System/Guild/GuildBossManager.cs
@@ -77,43 +77,20 @@
     // "info":{"LV":106,"Job":1,"Name":"涓诲叕3016219","FacePic":0,"FightPower":1831995,"RealmLV":12,"ServerID":86,"TitleID":0,"Face":0},
     public HA513_tagMCFamilyActionInfo.tagMCFamilyAction GetGuildBossAction()
     {
-        GuildManager.Instance.TryGetFamilyActions(GuildManager.GuildBossActionType, out var familyActions);
-        if (familyActions == null)
-        {
-            return null;
-        }
-        foreach (var action in familyActions)
-        {
-            if (action.Value1 == 1)
-            {
-                return action;
-            }
-        }
+
         return null;
     }
 
-    int lastGuildBossTime;
 
     // 鑾峰彇鍏細涓殑浼ゅ璁板綍鍋氭帓鍚�
-    public void UpdateGuildBossInfo(HA513_tagMCFamilyActionInfo vNetData)
+    public bool UpdateGuildBossInfo(HA513_tagMCFamilyActionInfo vNetData)
     {
         if (vNetData.ActionType != GuildManager.GuildBossActionType)
         {
-            return;
+            return false;
         }
 
-        GuildManager.Instance.TryGetFamilyActions(GuildManager.GuildBossActionType, out var familyActions);
-        if (familyActions == null)
-        {
-            return;
-        }
-        foreach (var action in familyActions)
-        {
-            if (action.Value1 == 1)
-            {
-                return;
-            }
-        }
+        return true;
     }
 
 }
diff --git a/Main/System/Guild/GuildBossWin.cs b/Main/System/Guild/GuildBossWin.cs
index 435e12f..f51875b 100644
--- a/Main/System/Guild/GuildBossWin.cs
+++ b/Main/System/Guild/GuildBossWin.cs
@@ -69,7 +69,7 @@
     {
         GlobalTimeEvent.Instance.secondEvent += OnSecondEvent;
         PlayerDatas.Instance.playerDataRefreshEvent += OnPlayerDataRefresh;
-        GuildManager.Instance.FamilyActionInfoEvent += OnFamilyActionInfoEvent;
+        // GuildManager.Instance.FamilyActionInfoEvent += OnFamilyActionInfoEvent;
         Display();
     }
 
@@ -77,7 +77,7 @@
     {
         GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent;
         PlayerDatas.Instance.playerDataRefreshEvent -= OnPlayerDataRefresh;
-        GuildManager.Instance.FamilyActionInfoEvent -= OnFamilyActionInfoEvent;
+        // GuildManager.Instance.FamilyActionInfoEvent -= OnFamilyActionInfoEvent;
     }
 
 
diff --git a/Main/System/Guild/GuildChangeNameWin.cs b/Main/System/Guild/GuildChangeNameWin.cs
index bd52a54..8992a21 100644
--- a/Main/System/Guild/GuildChangeNameWin.cs
+++ b/Main/System/Guild/GuildChangeNameWin.cs
@@ -1,5 +1,6 @@
 using System.Collections;
 using System.Collections.Generic;
+using System.Text;
 using UnityEngine;
 using UnityEngine.UI;
 
@@ -83,8 +84,8 @@
             UIManager.Instance.CloseWindow<GuildOPWin>();
             var pack = new CA611_tagCMRenameFamily();
             pack.NewName = guildNameText.text;
-            pack.NewNameLen = (byte)pack.NewName.Length;
-            // GameNetSystem.Instance.SendInfo(pack);
+            pack.NewNameLen = (byte)Encoding.Default.GetBytes(pack.NewName).Length;
+            GameNetSystem.Instance.SendInfo(pack);
         }
     }
 
diff --git a/Main/System/Guild/GuildEmblemModel.cs b/Main/System/Guild/GuildEmblemModel.cs
index 1f830a1..764c811 100644
--- a/Main/System/Guild/GuildEmblemModel.cs
+++ b/Main/System/Guild/GuildEmblemModel.cs
@@ -14,6 +14,7 @@
 public class GuildEmblemModel : GameSystemManager<GuildEmblemModel>
 {
     
+    public Dictionary<int, HA513_tagMCFamilyActionInfo.tagMCFamilyAction> emblemActions = new Dictionary<int, HA513_tagMCFamilyActionInfo.tagMCFamilyAction>();
 
 
     private int m_NowChooseEmblemId;
@@ -51,15 +52,15 @@
     public override void Init()
     {
         PlayerDatas.Instance.fairyData.OnRefreshFairyInfo += OnRefreshFairyInfo;
-        GuildManager.Instance.FamilyActionInfoEvent += OnFamilyActionInfoEvent;
         DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent += OnBeforePlayerDataInitialize;
+        GuildManager.Instance.EnterOrQuitGuildEvent += OnEnterOrQuitGuildEvent;
     }
 
     public override void Release()
     {
         PlayerDatas.Instance.fairyData.OnRefreshFairyInfo -= OnRefreshFairyInfo;
-        GuildManager.Instance.FamilyActionInfoEvent -= OnFamilyActionInfoEvent;
         DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent -= OnBeforePlayerDataInitialize;
+        GuildManager.Instance.EnterOrQuitGuildEvent -= OnEnterOrQuitGuildEvent;
     }
 
     public void OnBeforePlayerDataInitialize()
@@ -69,6 +70,12 @@
         createEmblemWord = "";
         oldShowActiveList.Clear();
         showList.Clear();
+        emblemActions.Clear();
+    }
+
+    public void OnEnterOrQuitGuildEvent(bool isEnter)
+    {
+        OnBeforePlayerDataInitialize();
     }
 
     private void OnRefreshFairyInfo()
@@ -236,11 +243,6 @@
     }
 
 
-    void OnFamilyActionInfoEvent(int familyId, int actionType)
-    {
-        UpdateRedPoint();
-    }
-
     public bool IsLimitTime(int emblemId, out HA513_tagMCFamilyActionInfo.tagMCFamilyAction familyAction)
     {
         familyAction = new HA513_tagMCFamilyActionInfo.tagMCFamilyAction();
@@ -269,20 +271,33 @@
         return PlayerDatas.Instance.fairyData.mine.FmLV == 3;
     }
 
+
+
+    // 鏇存柊寰界珷淇℃伅
+    public bool UpdateEmblemAction(HA513_tagMCFamilyActionInfo _package)
+    {
+        if (_package.ActionType != GuildManager.FamilyActionsType)
+        {
+            return false;
+        }
+
+        for (int i = 0; i < _package.FamilyActionList.Length; i++)
+        {
+            int emblemId = (int)_package.FamilyActionList[i].Value1;
+            emblemActions[emblemId] = _package.FamilyActionList[i];
+        }
+
+        
+        UpdateRedPoint();
+        return true;
+    }
+
     // 鑾峰緱寰界珷璁板綍淇℃伅淇℃伅锛堟椿鍔ㄩ�斿緞鑾峰彇鐨勫窘绔�,瀹氬埗寰界珷锛夛紝value1鏄窘绔營D锛寁alue2鏄窘绔犲埌鏈熸椂闂�
     private bool TryGetfamilyAction(int emblemId, out HA513_tagMCFamilyActionInfo.tagMCFamilyAction familyAction)
     {
-        familyAction = new HA513_tagMCFamilyActionInfo.tagMCFamilyAction();
-        if (GuildManager.Instance.TryGetFamilyActions(GuildManager.FamilyActionsType, out var actions))
+        if (emblemActions.TryGetValue(emblemId, out familyAction))
         {
-            for (int i = 0; i < actions.Length; i++)
-            {
-                if (actions[i].Value1 == emblemId)
-                {
-                    familyAction = actions[i];
-                    return true;
-                }
-            }
+            return true;
         }
 
         return false;
diff --git a/Main/System/Guild/GuildManager.cs b/Main/System/Guild/GuildManager.cs
index 71066f3..98015a1 100644
--- a/Main/System/Guild/GuildManager.cs
+++ b/Main/System/Guild/GuildManager.cs
@@ -12,6 +12,7 @@
 {
     // 瀹舵棌鑷畾涔夎褰曠被鍨�
     public const int CustomyActionType = 0;     //閫氱敤
+    public const int MemberChangeActionType = 12;      //鍏細鍙樻洿璁板綍
     public const int FamilyActionsType = 15;     // 鍏細璁板綍寰界珷绫诲瀷15
     public const int ZBGFamilyActionType = 16;  // 鐝嶅疂闃佽褰曠被鍨�
     public const int GuildBossActionType = 18;  //璁ㄤ紣
@@ -84,6 +85,11 @@
         guildChanged = false;
         applyList.Clear();
         PlayerDatas.Instance.fairyData.ClearData();
+
+        isQueryZBGYet = false;
+        zhenbaogeCutState = 0;
+        familyZBGActions.Clear();
+        sortPlayerCut.Clear();
     }
     
     //閫�鍑哄叕浼�
@@ -95,10 +101,10 @@
         UIManager.Instance.GetUI<MainWin>()?.ClickFunc(0);
 
 
-        isQueryZBGYet = false;
-        zhenbaogeCutState = 0;
-        familyZBGActions.Clear();
-        sortPlayerCut.Clear();
+        // isQueryZBGYet = false;
+        // zhenbaogeCutState = 0;
+        // familyZBGActions.Clear();
+        // sortPlayerCut.Clear();
         
         UpdateZBGRedpoint();
         UpdateDonateRedPoint();
@@ -393,7 +399,6 @@
 
 
 
-
     #region 浠欑洘鍟嗗簵寮�鍚�
     public int fairyStoreLimit = 0;
     public bool fairyStoreOpen
@@ -438,6 +443,31 @@
             return;
         }
 
+        // 琛屽晢 鐮嶄环
+        if (UpdateHawkerAction(_package))
+        {
+            return;
+        }
+
+        // 寰界珷
+        if (GuildEmblemModel.Instance.UpdateEmblemAction(_package))
+        {
+            return;
+        }
+
+        // 鍏細璁ㄤ紣
+        if (GuildBossManager.Instance.UpdateGuildBossInfo(_package))
+        {
+            return;
+        }
+
+        //涓婇潰鍚勪釜鍔熻兘瑕乺eturn
+        UpdataCommonAction(_package);
+    }
+
+    // 閫氱敤璁板綍 鍙�傜敤鍗曟潯鏁版嵁鐨勮褰曟儏鍐� 鎴栨湁鏈嶅姟绔繚璇佸垪琛ㄥ叏閮ㄤ俊鎭洿鎺ヨ鐩栵紝鍏朵粬鍔熻兘姣旇緝澶嶆潅鍚勮嚜璐熻矗瀛樺偍
+    void UpdataCommonAction(HA513_tagMCFamilyActionInfo _package)
+    {
         if (!familyActions.ContainsKey((int)_package.FamilyID))
         {
             familyActions.Add((int)_package.FamilyID, new Dictionary<int, HA513_tagMCFamilyActionInfo.tagMCFamilyAction[]>());
@@ -445,11 +475,10 @@
 
         familyActions[(int)_package.FamilyID][_package.ActionType] = _package.FamilyActionList;
 
-        UpdateHawkerAction(_package);
-
         FamilyActionInfoEvent?.Invoke((int)_package.FamilyID, _package.ActionType);
     }
 
+    // 閫氱敤璁板綍 
     public bool TryGetFamilyActions(int actionType, out HA513_tagMCFamilyActionInfo.tagMCFamilyAction[] familyAction)
     {
         familyAction = null;
@@ -801,11 +830,11 @@
 
 
     //鏇存柊鐮嶄环淇℃伅
-    public void UpdateHawkerAction(HA513_tagMCFamilyActionInfo vNetData)
+    public bool UpdateHawkerAction(HA513_tagMCFamilyActionInfo vNetData)
     {
         if (vNetData.ActionType != ZBGFamilyActionType)
         {
-            return;
+            return false;
         }
         bool restart = false;
         if (vNetData.FamilyActionList.Length == 1 && vNetData.FamilyActionList[0].Value1 == 1)
@@ -843,6 +872,8 @@
 
         UpdateFamilyActionEvent?.Invoke(restart);
         UpdateZBGRedpoint();
+
+        return true;
     }
 
     //鐮嶄环浜烘暟
diff --git a/Main/System/Guild/GuildOPWin.cs b/Main/System/Guild/GuildOPWin.cs
index 8845c09..2298c04 100644
--- a/Main/System/Guild/GuildOPWin.cs
+++ b/Main/System/Guild/GuildOPWin.cs
@@ -77,6 +77,7 @@
 
     void OnRefreshFairyInfo()
     {
+        Display();
     }
 
 
diff --git a/Main/System/Hero/UIHeroController.cs b/Main/System/Hero/UIHeroController.cs
index 4712be1..1d8999b 100644
--- a/Main/System/Hero/UIHeroController.cs
+++ b/Main/System/Hero/UIHeroController.cs
@@ -71,7 +71,7 @@
 		}
 
 		onComplete = _onComplete;
-		pool = GameObjectPoolManager.Instance.RequestPool(UILoader.LoadPrefab("UIHero"));
+		pool = GameObjectPoolManager.Instance.GetPool(UILoader.LoadPrefab("UIHero"));
 
 		if (!transform.gameObject.activeSelf)
 		{
diff --git a/Main/System/Horse/HorseController.cs b/Main/System/Horse/HorseController.cs
index 298a69f..55dbf5e 100644
--- a/Main/System/Horse/HorseController.cs
+++ b/Main/System/Horse/HorseController.cs
@@ -34,7 +34,7 @@
 		this.transform.localScale = Vector3.one * scale;
 
 		onComplete = _onComplete;
-		pool = GameObjectPoolManager.Instance.RequestPool(UILoader.LoadPrefab("UIHorse"));
+		pool = GameObjectPoolManager.Instance.GetPool(UILoader.LoadPrefab("UIHorse"));
 
 		if (!transform.gameObject.activeSelf)
 		{
diff --git a/Main/System/Login/LoginWin.cs b/Main/System/Login/LoginWin.cs
index 85b2e38..2320d37 100644
--- a/Main/System/Login/LoginWin.cs
+++ b/Main/System/Login/LoginWin.cs
@@ -98,6 +98,10 @@
         AutoFightModel.Instance.isAutoAttack = false;
         AutoFightModel.Instance.isPause = false;
 
+        if (!LoginManager.Instance.sdkLogined)
+        {
+            SDKUtils.Instance.FreePlatformLogin();
+        }
     }
 
     protected override void OnOpenAnimationComplete()
@@ -264,7 +268,7 @@
     private void SwitchAccount()
     {
         SDKUtils.Instance.FreePlatformLoginout();
-        LoginManager.Instance.sdkLogined = true;
+        LoginManager.Instance.sdkLogined = false;
     }
 
     private void VeiwNotice()
diff --git a/Main/System/Main/HomeWin.cs b/Main/System/Main/HomeWin.cs
index d486a3e..bdd24a0 100644
--- a/Main/System/Main/HomeWin.cs
+++ b/Main/System/Main/HomeWin.cs
@@ -11,7 +11,6 @@
 /// </summary>
 public class HomeWin : UIBase
 {
-
     //缁忛獙鍖�
     [SerializeField] Text playerLevelText;
     [SerializeField] SmoothSlider expSlider;
@@ -68,7 +67,24 @@
     [SerializeField] Button horseBtn;
     [SerializeField] HorseController horseImg;
     [SerializeField] Text horseLVText;
-    
+
+    //鑱婂ぉ
+    [SerializeField] Button chatBtn;
+    [SerializeField] Transform transFastChat;
+    [SerializeField] InputField inputFastChat;
+    [SerializeField] ButtonEx btnFastChatSend;
+    [SerializeField] ImageEx imgFastChatSend;
+    [SerializeField] TextEx txtFastChatSend;
+    [SerializeField] ButtonEx btnFastChatClose;
+    [SerializeField] ButtonEx btnChatWin;
+    [SerializeField] TextEx txtChatChannel;
+
+
+    [SerializeField] Transform transChatBulletView;
+    GameObject chatBulletViewPrefab;
+
+
+
     /// <summary>
     /// 鍒濆鍖栫粍浠�
     /// </summary>
@@ -122,12 +138,55 @@
         });
 
         restBtn.AddListener(GotoRest);
-        funcColBtn.AddListener(()=>
+        funcColBtn.AddListener(() =>
         {
             rightFuncInHome.ShowFuncCol(true);
         });
 
         horseBtn.AddListener(OpenHorse);
+
+        chatBtn.SetListener(() =>
+        {
+            if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.Chat, true))
+                return;
+
+            transFastChat.SetActive(true);
+            chatBtn.SetActive(false);
+            UpdateChat(ChatManager.Instance.nowChatTab);
+
+        });
+        btnFastChatClose.SetListener(() =>
+        {
+            transFastChat.SetActive(false);
+            chatBtn.SetActive(true);
+        });
+        btnChatWin.SetListener(() =>
+        {
+            transFastChat.SetActive(false);
+            chatBtn.SetActive(true);
+            UIManager.Instance.OpenWindow<ChatWin>();
+        });
+
+        btnFastChatSend.SetListener(() =>
+        {
+            // 濡傛灉鍦ㄨ亰澶╄緭鍏ョ晫闈㈡棤杈撳叆鏂囧瓧鐐瑰嚮鍙戦�侊紝鍒欏叧闂亰澶╄緭鍏ョ晫闈�
+            if (string.IsNullOrEmpty(inputFastChat.text))
+            {
+                transFastChat.SetActive(false);
+                chatBtn.SetActive(true);
+                return;
+            }
+
+            if (!ChatManager.Instance.CheckChatLimit(inputFastChat.text, out int errorCode))
+            {
+                ChatManager.Instance.ShowChatErrorTip(errorCode);
+                return;
+            }
+            ChatManager.Instance.SendChatInfo(ChatManager.Instance.nowChatChannel, inputFastChat.text);
+            ChatManager.Instance.AddChatChannelSendTime(ChatManager.Instance.nowChatChannel, TimeUtility.AllSeconds);
+            UpdateSendButton();
+            inputFastChat.text = string.Empty;
+        });
     }
 
 
@@ -148,6 +207,12 @@
         officialTip.SetActive(OfficialRankManager.Instance.CanOfficialLVUP());
 
         DisplayHorse();
+
+        DisplayChatBulletView();
+        chatBtn.SetActive(true);
+        transFastChat.SetActive(false);
+        inputFastChat.characterLimit = ChatManager.Instance.characterLimit;
+        UpdateSendButton();
     }
 
     protected override void OnPreOpen()
@@ -167,6 +232,8 @@
         FirstChargeManager.Instance.OnFirstChargeTaskUpdateEvent += OnFirstChargeTaskUpdateEvent;
         OfficialRankManager.Instance.RealmMissionRefreshEvent += OnOfficialCanLVUpEvent;
         HorseManager.Instance.OnHorseUpdateEvent += DisplayHorse;
+        ChatManager.Instance.OnChatTabChangeEvent += OnChatTabChangeEvent;
+        GuildManager.Instance.EnterOrQuitGuildEvent += EnterOrQuitGuildEvent;
         Display();
         DisplayFirstChargeBtn();
 
@@ -195,8 +262,54 @@
         FirstChargeManager.Instance.OnFirstChargeTaskUpdateEvent -= OnFirstChargeTaskUpdateEvent;
         OfficialRankManager.Instance.RealmMissionRefreshEvent -= OnOfficialCanLVUpEvent;
         HorseManager.Instance.OnHorseUpdateEvent -= DisplayHorse;
+        ChatManager.Instance.OnChatTabChangeEvent -= OnChatTabChangeEvent;
+        GuildManager.Instance.EnterOrQuitGuildEvent -= EnterOrQuitGuildEvent;
+
         //  鍏抽棴鐨勬椂鍊欐妸鎴樻枟鐣岄潰涔熺粰鍏充簡 铏界劧鏄湪澶栭潰寮�鐨�
         UIManager.Instance.CloseWindow<BattleWin>();
+    }
+
+    private void UpdateSendButton()
+    {
+        bool isCanSend = ChatManager.Instance.IsCanSend(ChatManager.Instance.nowChatChannel, out int remainingSeconds);
+        btnFastChatSend.interactable = isCanSend;
+        imgFastChatSend.gray = !isCanSend;
+        txtFastChatSend.text = isCanSend ? Language.Get("Chat11") : Language.Get("Chat14", remainingSeconds);
+        txtFastChatSend.colorType = isCanSend ? TextColType.NavyBrown : TextColType.LightWhite;
+    }
+
+
+    private void EnterOrQuitGuildEvent(bool obj)
+    {
+        if (!obj)
+        {
+            UpdateChat(ChatManager.Instance.nowChatTab);
+        }
+    }
+
+    private void OnChatTabChangeEvent(ChatTab tab)
+    {
+        UpdateChat(tab);
+    }
+
+    void UpdateChat(ChatTab tab)
+    {
+        txtChatChannel.text = ChatManager.Instance.GetChatTabName(tab);
+    }
+
+    void DisplayChatBulletView()
+    {
+        if (chatBulletViewPrefab == null)
+        {
+            chatBulletViewPrefab = UIUtility.CreateWidget("ChatBulletView", "ChatBulletView");
+        }
+        chatBulletViewPrefab.transform.SetParentEx(transChatBulletView.transform, Vector3.zero, Quaternion.identity, Vector3.one);
+        // 鏂板锛氱‘淇� ChatBulletView 缁勪欢鍚敤
+        // var chatBulletView = chatBulletViewPrefab.GetComponent<ChatBulletView>();
+        // if (chatBulletView != null)
+        // {
+        //     chatBulletView.enabled = true;
+        // }
     }
 
     void OnOfficialCanLVUpEvent()
@@ -308,7 +421,7 @@
         if (showEffect)
         {
             headEffect.transform.DOLocalMove(new Vector3(400 * expSlider.value - 200 - 24, 0, 0), 0.5f);
-            headEffect.Play(closePMA:true);
+            headEffect.Play(closePMA: true);
         }
     }
 
@@ -358,7 +471,7 @@
             GameNetSystem.Instance.SendInfo(getReward);
             return;
         }
-        
+
         TaskManager.Instance.ClickTask();
     }
 
@@ -509,6 +622,7 @@
     private void OnSecondEvent()
     {
         DisplayFirstChargeBtn();
+        UpdateSendButton();
     }
 
     void OnUnLockHeroCountEvent()
@@ -525,7 +639,7 @@
             //equipShowSwitch;//褰撳墠閰嶇疆鐨勫潗楠戝瑙侷D瀛樺偍鍦紙鏈�澶ф敮鎸� 1~999锛�
             var skinConfig = HorseSkinConfig.Get(HorseManager.Instance.GetUsingHorseSkinID(true));
             horseImg.Create(skinConfig.SkinID, 0, 0.6f);
-            horseLVText.text = Language.Get("Horse8",HorseManager.Instance.classLV, HorseManager.Instance.horseLV);
+            horseLVText.text = Language.Get("Horse8", HorseManager.Instance.classLV, HorseManager.Instance.horseLV);
         }
         else
         {
diff --git a/Main/System/Message/SysNotifyMgr.cs b/Main/System/Message/SysNotifyMgr.cs
index 1e7710e..9da1a2f 100644
--- a/Main/System/Message/SysNotifyMgr.cs
+++ b/Main/System/Message/SysNotifyMgr.cs
@@ -111,7 +111,6 @@
 #if UNITY_EDITOR
             string hint = Language.Get("L1093", key);
             ScrollTip.ShowTip(hint);
-            ChatManager.Instance.RevChatInfo(hint);
 #endif
         }
         else
@@ -234,20 +233,13 @@
                     ServerTipDetails.ShowServerTip(msg, tipInfoList, order);
                     break;
                 case SysNotifyType.SysMarqueeTip:
-                    ServerTipDetails.ShowMarquee(msg, tipInfoList,order);
+                    ServerTipDetails.ShowMarquee(msg, tipInfoList, order);
                     break;
-
-                case SysNotifyType.SysChanelTip:
-                    ChatManager.Instance.RevChatInfo(msg, tipInfoList);
+                case SysNotifyType.ChatChannelWorld:
+                    ChatManager.Instance.AddSysData(msg, tipInfoList, ChatChannel.World);
                     break;
-                case SysNotifyType.SysFairyQuestionTip:
-                    ChatManager.Instance.RevChatInfo(msg, tipInfoList, ChatInfoType.FairyQuestion);
-                    break;
-                case SysNotifyType.SysFairyTip:
-                    ChatManager.Instance.RevChatInfo(msg, tipInfoList, ChatInfoType.FairyTip);
-                    break;
-                case SysNotifyType.SysTeamTip:
-                    ChatManager.Instance.RevChatInfo(msg, tipInfoList, ChatInfoType.TeamTip);
+                case SysNotifyType.ChatChannelGuild:
+                    ChatManager.Instance.AddSysData(msg, tipInfoList, ChatChannel.Guild);
                     break;
                 case SysNotifyType.SysRealmTip:
                     if (OnSysTipEvent != null)
@@ -260,9 +252,7 @@
                 // case SysNotifyType.SysEvenKill:
                 //     BattleHint.Instance.ReceiveEvenKill(msg, tipInfoList);
                 //     break;
-                case SysNotifyType.SysFactionTip:
-                    ChatManager.Instance.RevChatInfo(msg, tipInfoList, ChatInfoType.default2);
-                    break;
+
 
             }
         }
@@ -282,7 +272,8 @@
         SysChatWin = 6, //鑱婂ぉ浣嶇疆鐨勬彁绀�
         SysEvenKill = 7,//涓婂彜鎴樺満杩炴潃鎻愮ず
         SysFixedTip1 = 11,//鍥哄畾鎻愮ず2
-        SysChanelTip = 20,//绯荤粺棰戦亾鏄剧ず
+        ChatChannelWorld = 20,//鑱婂ぉ-涓栫晫棰戦亾
+        ChatChannelGuild = 21,//鑱婂ぉ-鍏細棰戦亾
         SysFairyQuestionTip = 31,//浠欑洘棰戦亾闂瓟鎻愮ず
         SysFairyTip = 32,//浠欑洘棰戦亾淇℃伅鎻愮ず
         SysTeamTip = 41,//闃熶紞棰戦亾鎻愮ず
diff --git a/Main/System/PhantasmPavilion/ChatBubbleHelper.cs b/Main/System/PhantasmPavilion/ChatBubbleHelper.cs
index eccfc81..4f01ca0 100644
--- a/Main/System/PhantasmPavilion/ChatBubbleHelper.cs
+++ b/Main/System/PhantasmPavilion/ChatBubbleHelper.cs
@@ -1,20 +1,18 @@
 public static class ChatBubbleHelper
 {
-
-
-    public static int GetOtherChatBubbleID(int nowID)
+    public static int GetOtherChatBubbleID(int job, int nowID)
     {
-        return 0;//PhantasmPavilionModel.Instance.GetNowOtherChatBubbleID(nowID);
+        int defaultID = GetChatBubbleDefaultID(job);
+        return ChatBubbleBoxConfig.HasKey(nowID) ? nowID : defaultID;
     }
 
     public static int GetMyChatBubbleID()
     {
-        return 0;//PhantasmPavilionModel.Instance.GetNowChatBubbleID();
+        return PhantasmPavilionManager.Instance.TryGetNowShowID(PhantasmPavilionType.ChatBox, out int defaultID) ? defaultID : 0;
     }
 
-    public static int GetChatBubbleDefaultID()
+    public static int GetChatBubbleDefaultID(int job)
     {
-        // PhantasmPavilionModel.Instance.TryGetDefaultID(PhantasmPavilionTab.ChatBubble, 0, out int defaultID);
-        return 0;//defaultID;
+        return PhantasmPavilionManager.Instance.TryGetDefaultID(PhantasmPavilionType.ChatBox, job, out int defaultID) ? defaultID : 0;
     }
 }
\ No newline at end of file
diff --git a/Main/System/PhantasmPavilion/PhantasmPavilionManager.cs b/Main/System/PhantasmPavilion/PhantasmPavilionManager.cs
index 68a857f..31e4118 100644
--- a/Main/System/PhantasmPavilion/PhantasmPavilionManager.cs
+++ b/Main/System/PhantasmPavilion/PhantasmPavilionManager.cs
@@ -289,6 +289,33 @@
         }
     }
 
+    public void ShowChatBox(ImageEx imgFace, UIFrame uiFrame, int resourceType, string resourceValue)
+    {
+        switch (resourceType)
+        {
+            // 闈欐�佸浘
+            case 1:
+                imgFace.enabled = true;
+                uiFrame.enabled = false;
+                if (!IconConfig.HasKey(resourceValue))
+                    return;
+                imgFace.SetSprite(resourceValue);
+                break;
+            // 搴忓垪甯�
+            case 3:
+                imgFace.enabled = true;
+                uiFrame.enabled = true;
+                imgFace.sprite = null;
+                imgFace.overrideSprite = null;
+
+                if (!UIFrameMgr.Inst.ContainsDynamicImage(resourceValue))
+                    break;
+                uiFrame.ResetFrame(resourceValue);
+                uiFrame.enabled = true;
+                break;
+        }
+    }
+
     public bool TryGetInfo(PhantasmPavilionType type, int id, out PhantasmPavilionData info)
     {
         info = null;
diff --git a/Main/System/Settlement/BattleSettlementManager.cs b/Main/System/Settlement/BattleSettlementManager.cs
index 169607e..d477cf8 100644
--- a/Main/System/Settlement/BattleSettlementManager.cs
+++ b/Main/System/Settlement/BattleSettlementManager.cs
@@ -221,7 +221,7 @@
             //涓汉鎴樻姤  璺緞锛� C:\TurnFightReport\S鏈嶅姟鍣ㄧ紪鍙穃鏃ユ湡\鐜╁ID\鍔熻兘鍦板浘ID\鎴樻姤GUID
             assetVersionUrl = $"{url}/S{serverID}/{date}/{PlayerDatas.Instance.baseData.PlayerID}/{mapID}/{guid}.tfr";
         }
-
+        Debug.Log($"璇锋眰鎴樻姤: {assetVersionUrl}");
         HttpRequest.Instance.UnityWebRequestTurnFightGet(assetVersionUrl, guid, 3, OnGetTurnFightData);
     }
 
diff --git a/Main/System/SystemSetting/ChatSetting.cs b/Main/System/SystemSetting/ChatSetting.cs
deleted file mode 100644
index faee470..0000000
--- a/Main/System/SystemSetting/ChatSetting.cs
+++ /dev/null
@@ -1,184 +0,0 @@
-锘縰sing System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-public enum ChatBoolType
-{
-    ChannelSystem = 0 , //绯荤粺棰戦亾
-    ChannelWorld,//涓栫晫棰戦亾
-    ChannelATeam,//缁勯槦棰戦亾
-    ChannelTeam,//闃熶紞棰戦亾
-    ChannelBugle,//鍠囧彮棰戦亾
-    ChannelGrad,//浠欑洘棰戦亾
-    ChannelArea,//鍖哄煙棰戦亾
-    //ChannelAlliance,//鍚岀洘棰戦亾
-
-    Voice1,
-    Voice2,
-    Voice3,
-
-    GradVoiceWifi,  //浠欑洘璇煶Wifi
-    PrivateChatVoiceWifi,//绉佽亰璇煶Wifi
-    TeamVoiceWifi,//闃熶紞璇煶Wifi
-    WorldVoiceWifi,//涓栫晫璇煶Wifi
-    AreaVoiceWifi,//鍖哄煙璇煶Wifi
-   // AllianceVoiceWifi, //鍚岀洘璇煶Wifi
-
-    GradVoice4G,//浠欑洘璇煶4G
-    PrivatChatVoice4G,//绉佽亰璇煶4G
-    TeamVoice4G,//闃熶紞璇煶4G
-    WorldVoice4G,//涓栫晫璇煶4G
-    AreaVoice4G,//鍖哄煙璇煶4G
-                //AllianceVoice4G, //鍚岀洘璇煶4G
-                //鍚庣画IL寮�鍙戞坊鍔犻璁�
-    default1,
-    default2,
-    default3,
-    default4,
-    default5,
-    default6,
-    default7,
-    default8,
-    default9,
-    default10,
-}
-
- 
-public class ChatSetting : Singleton<ChatSetting>
-
-{
-    const string ChatBoolSet_Key = "ChatBoolSet";
-
-    public event Action<ChatBoolType, bool> RefreshChatSetAct;
-
-    #region 缂撳瓨鏁版嵁
-    public Dictionary<ChatBoolType, bool> boolSetDict { get; private set; }
-    public void GetLoginBoolSet()
-    {
-        boolSetDict = new Dictionary<ChatBoolType, bool>();
-        for (int i = 0; i < 20; i++)
-        {
-            if (!boolSetDict.ContainsKey((ChatBoolType)i))
-            {
-                boolSetDict.Add((ChatBoolType)i, SettingMgr.Instance.GetAccountSetBoolInfo(((ChatBoolType)i).ToString()));
-            }
-
-        }
-    }
-    #endregion
-
-    public void SetBoolSetStr(ChatBoolType type, bool isOpen)
-    {
-        SettingMgr.Instance.SetAccountSetStr(type.ToString(),isOpen.ToString());
-        switch (type) {
-            case ChatBoolType.ChannelSystem:
-                ChatManager.Instance.SetChatChannelShow(ChatInfoType.System, isOpen);
-                break;
-            case ChatBoolType.ChannelWorld:
-                ChatManager.Instance.SetChatChannelShow(ChatInfoType.World, isOpen);
-                break;
-            case ChatBoolType.ChannelATeam:
-                ChatManager.Instance.SetChatChannelShow(ChatInfoType.Invite, isOpen);
-                break;
-            case ChatBoolType.ChannelTeam:
-                ChatManager.Instance.SetChatChannelShow(ChatInfoType.Team, isOpen);
-                break;
-            case ChatBoolType.ChannelBugle:
-                ChatManager.Instance.SetChatChannelShow(ChatInfoType.Trumpet, isOpen);
-                break;
-            case ChatBoolType.ChannelGrad:
-                ChatManager.Instance.SetChatChannelShow(ChatInfoType.Fairy, isOpen);
-                break;
-            case ChatBoolType.ChannelArea:
-                ChatManager.Instance.SetChatChannelShow(ChatInfoType.Area, isOpen);
-                break;
-        }
-
-        if (boolSetDict != null)
-        {
-            if (boolSetDict.ContainsKey(type))
-            {
-                boolSetDict[type] = isOpen;
-            }
-        }
-
-        if(RefreshChatSetAct != null)
-        {
-            RefreshChatSetAct(type,isOpen);
-        }
-    }
-
-    public bool GetBool(ChatBoolType type)
-    {
-        if (boolSetDict != null)
-        {
-            bool isOpen = false;
-            boolSetDict.TryGetValue(type, out isOpen);
-            return isOpen;
-        }
-        else
-        {
-            return SettingMgr.Instance.GetAccountSetBoolInfo(type.ToString());
-        }
-    }
-
-    public bool GetAutoPlayVoice(ChatInfoType type, int netState)
-    {
-        if (netState == 0)
-        {
-            return false;
-        }
-        switch (type)
-        {
-            case ChatInfoType.World:
-                if (netState == 2)
-                {
-                    return GetBool(ChatBoolType.WorldVoiceWifi);
-                }
-                else
-                {
-                    return GetBool(ChatBoolType.WorldVoice4G);
-                }
-            case ChatInfoType.Area:
-                if (netState == 2)
-                {
-                    return GetBool(ChatBoolType.AreaVoiceWifi);
-                }
-                else
-                {
-                    return GetBool(ChatBoolType.AreaVoice4G);
-                }
-            case ChatInfoType.Team:
-                if (netState == 2)
-                {
-                    return GetBool(ChatBoolType.TeamVoiceWifi);
-                }
-                else
-                {
-                    return GetBool(ChatBoolType.TeamVoice4G);
-                }
-            case ChatInfoType.Fairy:
-                if (netState == 2)
-                {
-                    return GetBool(ChatBoolType.GradVoiceWifi);
-                }
-                else
-                {
-                    return GetBool(ChatBoolType.GradVoice4G);
-                }
-            case ChatInfoType.Friend:
-                if (netState == 2)
-                {
-                    return GetBool(ChatBoolType.PrivateChatVoiceWifi);
-                }
-                else
-                {
-                    return GetBool(ChatBoolType.PrivatChatVoice4G);
-                }
-            case ChatInfoType.CrossServer:
-                return false;
-        }
-        return false;
-    }
-}
\ No newline at end of file
diff --git a/Main/System/SystemSetting/ChatSetting.cs.meta b/Main/System/SystemSetting/ChatSetting.cs.meta
deleted file mode 100644
index 96164ee..0000000
--- a/Main/System/SystemSetting/ChatSetting.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: f233865cd812ec342a52b00b4af26d27
-MonoImporter:
-  externalObjects: {}
-  serializedVersion: 2
-  defaultReferences: []
-  executionOrder: 0
-  icon: {instanceID: 0}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 
diff --git a/Main/System/Tip/ScrollTip.cs b/Main/System/Tip/ScrollTip.cs
index b58123b..dbb20af 100644
--- a/Main/System/Tip/ScrollTip.cs
+++ b/Main/System/Tip/ScrollTip.cs
@@ -74,7 +74,7 @@
         if (pool == null)
         {
             var _prefab = UILoader.LoadPrefab("Tip");
-            pool = GameObjectPoolManager.Instance.RequestPool(_prefab);
+            pool = GameObjectPoolManager.Instance.GetPool(_prefab);
         }
         if (pool != null)
         {
diff --git a/Main/Utility/LanguageVerify.cs b/Main/Utility/LanguageVerify.cs
index 74e6a5e..94c452e 100644
--- a/Main/Utility/LanguageVerify.cs
+++ b/Main/Utility/LanguageVerify.cs
@@ -42,33 +42,6 @@
         return;
     }
 
-    public static uint toPlayer = 0;
-    public static string toPlayerName = string.Empty;
-    public static int toPlayerLevel = 0;
-    public void VerifyChat(string content, ChatInfoType channelType, Action<bool, string> callback)
-    {
-        int channel = 0;
-        var chatCenter = ChatCenter.Instance;
-        if (chatCenter.IsChatBanned || chatCenter.IsClientBan(channelType))
-        {
-            if (!(IsFairyFeast(channelType) || IsSystemChat(content)))
-            {
-                return;
-            }
-        }
-
-        if (!GetChannel(channelType, out channel))
-        {
-            return;
-        }
-        if (callback != null)
-        {
-            callback(true, content);
-            callback = null;
-        }
-
-    }
-
     Dictionary<long, List<string>> transferContents = new Dictionary<long, List<string>>();
     Dictionary<long, List<int>> splitContents = new Dictionary<long, List<int>>();
 
@@ -116,12 +89,9 @@
         AddMathcs(WordAnalysis.Color_Start_Regex.Matches(content));
         AddMathcs(WordAnalysis.Color_End_Regex.Matches(content));
         AddMathcs(ImgAnalysis.FaceRegex.Matches(content));
-        AddMathcs(ChatManager.InviteRegex.Matches(content));
         AddMathcs(WordAnalysis.Size_Start_Regex.Matches(content));
         AddMathcs(WordAnalysis.Size_End_Regex.Matches(content));
         AddMathcs(WordAnalysis.Space_Regex.Matches(content));
-        AddMathcs(ChatManager.KillRegex.Matches(content));
-        AddMathcs(ChatCenter.s_VoiceRegex.Matches(content));
         matchs.Sort((x, y) =>
         {
             return x.index.CompareTo(y.index);
@@ -137,12 +107,9 @@
         content = WordAnalysis.Color_Start_Regex.Replace(content, string.Empty);
         content = WordAnalysis.Color_End_Regex.Replace(content, string.Empty);
         content = ImgAnalysis.FaceRegex.Replace(content, string.Empty);
-        content = ChatManager.InviteRegex.Replace(content, string.Empty);
         content = WordAnalysis.Size_Start_Regex.Replace(content, string.Empty);
         content = WordAnalysis.Size_End_Regex.Replace(content, string.Empty);
         content = WordAnalysis.Space_Regex.Replace(content, string.Empty);
-        content = ChatManager.KillRegex.Replace(content, string.Empty);
-        content = ChatCenter.s_VoiceRegex.Replace(content, string.Empty);
         return content;
     }
 
@@ -173,57 +140,6 @@
         transferContents.Remove(tick);
         splitContents.Remove(tick);
         return sb.ToString();
-    }
-
-    bool IsSystemChat(string content)
-    {
-        if (ChatManager.InviteRegex.IsMatch(content)
-            || ChatManager.KillRegex.IsMatch(content))
-        {
-            return true;
-        }
-        return false;
-    }
-
-    bool GetChannel(ChatInfoType type, out int channel)
-    {
-        channel = 0;
-        switch (type)
-        {
-            case ChatInfoType.World:
-            case ChatInfoType.CrossServer:
-                channel = 0;
-                break;
-            case ChatInfoType.Team:
-                channel = 4;
-                break;
-            case ChatInfoType.Area:
-            case ChatInfoType.Trumpet:
-            case ChatInfoType.default1:
-                channel = 5;
-                break;
-            case ChatInfoType.Fairy:
-                channel = 2;
-                break;
-            case ChatInfoType.Friend:
-                channel = 3;
-                break;
-            default:
-                return false;
-        }
-        return true;
-    }
-
-    bool IsFairyFeast(ChatInfoType type)
-    {
-        // TODO YYL
-        // var dailyQuestModel = ModelCenter.Instance.GetModel<DailyQuestModel>();
-        // DailyQuestOpenTime dailyQuestOpenTime;
-        // if (dailyQuestModel.TryGetOpenTime((int)DailyQuestType.FairyFeast, out dailyQuestOpenTime))
-        // {
-        //     return type == ChatInfoType.Fairy && dailyQuestOpenTime.InOpenTime();
-        // }
-        return false;
     }
 
     public class VerifyResponse

--
Gitblit v1.8.0