lcy
8 天以前 c22bdd2562585c87d3fcfadcf94a4277b119a85c
76 【常规】聊天系统-客户端

1.新增玩家外观缓存机制,当聊天中的其他玩家更换外观时(名字,头像,头像框,称号时),统一该玩家所有聊天的外观表现为最新的
2.修复断线重连后聊天内容布局错位问题
3.修复断线重连后自动发送了错误弹幕问题
4个文件已修改
112 ■■■■ 已修改文件
Main/System/Chat/ChatManager.cs 66 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Chat/ChatPlayerOtherCell.cs 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Chat/ChatWin.cs 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Message/SysNotifyMgr.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Chat/ChatManager.cs
@@ -11,6 +11,9 @@
    //<ChannelType,TalkData>
    public Dictionary<ChatChannel, List<TalkData>> talkDict = new Dictionary<ChatChannel, List<TalkData>>();
    //用于缓存玩家的外观信息
    public Dictionary<uint, TalkData> playerInfoDict = new Dictionary<uint, TalkData>();
    public Dictionary<int, ChatBubbleData> chatBubbles = new Dictionary<int, ChatBubbleData>();
    //<ChannelType,时间戳>
    public Dictionary<int, int> chatChannelSendTime = new Dictionary<int, int>();
@@ -119,6 +122,8 @@
    private void OnBeforePlayerDataInitializeEvent()
    {
        talkDict.Clear();
        playerInfoDict.Clear();
        currentDay = -1;
        ParseChatBubbleConfig();
        nowChatChannel = ChatChannel.World;
        nowChatTab = ChatTab.World;
@@ -185,6 +190,11 @@
    public static int GetUTF8InfoLen(string msg)
    {
        return Encoding.UTF8.GetBytes(msg).Length;
    }
    public bool TryGetNewPlayerInfoByPlayerID(uint playerID, out TalkData talkData)
    {
        return playerInfoDict.TryGetValue(playerID, out talkData);
    }
    public bool TryGetBubble(int id, out ChatBubbleData bubble)
@@ -351,7 +361,7 @@
    }
    public int currentDay = -1;
    public void AddTalkData(ChatChannel type, TalkData data)
    public void AddTalkData(ChatChannel type, TalkData data, bool isSend)
    {
        //如果超过限制先删除旧数据
        TryDeleteTalkData(type);
@@ -360,10 +370,13 @@
            talkDict[type] = new List<TalkData>();
        }
        talkDict[type].Add(data);
        if (isSend)
        {
        OnUpdateTalkEvent?.Invoke(type, data);
    }
    }
    public bool TryAddDate(int allSeconds, ChatChannel type)
    public bool TryAddDate(int allSeconds, ChatChannel type, bool isSend)
    {
        DateTime talkTime = TimeUtility.GetTime((uint)allSeconds);
        if (talkTime.Day != currentDay)
@@ -375,17 +388,17 @@
                isDate = true,
                Content = Language.Get("Chat09", talkTime.Month, talkTime.Day),
                TalkTime = (uint)allSeconds,
            });
            }, isSend);
            return true;
        }
        return false;
    }
    public void AddSysData(string msg, ArrayList infoList, ChatChannel type)
    public void AddSysData(string msg, ArrayList infoList, ChatChannel type, bool isSend)
    {
        int allSeconds = TimeUtility.AllSeconds;
        // 如果隔天,增加日期行
        TryAddDate(allSeconds, type);
        TryAddDate(allSeconds, type, isSend);
        if (!talkDict.ContainsKey(type))
        {
@@ -399,7 +412,7 @@
            BubbleBox = 1,
            TalkTime = (uint)allSeconds,
            InfoList = new ArrayList(infoList),
        });
        }, isSend);
    }
    public void UpdateTalk(HB310_tagMCTalk vNetData)
@@ -415,7 +428,7 @@
        int allSeconds = TimeUtility.AllSeconds;
        // 如果隔天,增加日期行
        TryAddDate(allSeconds, type);
        TryAddDate(allSeconds, type, true);
        TalkData talkData = new TalkData()
        {
@@ -433,7 +446,9 @@
            ServerID = vNetData.ServerID,
            TalkTime = (uint)allSeconds,
        };
        AddTalkData(type, talkData);
        AddPlayerInfo(talkData);
        AddTalkData(type, talkData, true);
    }
    public void UpdateTalkCacheList(HB311_tagMCTalkCacheList vNetData)
@@ -453,13 +468,13 @@
        foreach (var info in vNetData.InfoList)
        {
            // 如果隔天,增加日期行
            TryAddDate((int)info.TalkTime, type);
            AddTalkData(type, new TalkData()
            TryAddDate((int)info.TalkTime, type, false);
            TalkData talkData = new TalkData()
            {
                ChannelType = vNetData.ChannelType,
                Name = info.Name,
                Name = UIHelper.ServerStringTrim(info.Name),
                PlayerID = info.PlayerID,
                Content = info.Content,
                Content = UIHelper.ServerStringTrim(info.Content),
                BubbleBox = info.BubbleBox,
                LV = info.LV,
                Job = info.Job,
@@ -469,9 +484,33 @@
                FacePic = info.FacePic,
                ServerID = info.ServerID,
                TalkTime = info.TalkTime,
            });
            };
            AddPlayerInfo(talkData);
            AddTalkData(type, talkData, false);
        }
        OnUpdateTalkCacheListEvent?.Invoke();
    }
    public event Action OnUpdatePlayerInfoEvent;
    public void AddPlayerInfo(TalkData data)
    {
        bool isChange = false;
        if (playerInfoDict.ContainsKey(data.PlayerID))
        {
            if (data.Name != playerInfoDict[data.PlayerID].Name||
            data.BubbleBox != playerInfoDict[data.PlayerID].BubbleBox||
            data.LV != playerInfoDict[data.PlayerID].LV||
            data.Job != playerInfoDict[data.PlayerID].Job||
            data.RealmLV != playerInfoDict[data.PlayerID].RealmLV||
            data.TitleID != playerInfoDict[data.PlayerID].TitleID||
            data.Face != playerInfoDict[data.PlayerID].Face||
            data.FacePic != playerInfoDict[data.PlayerID].FacePic)
            isChange = true;
        }
        playerInfoDict[data.PlayerID] = data;
        if (isChange)
            OnUpdatePlayerInfoEvent?.Invoke();
    }
    #region 标签页
    // 当前展示的频道入口
@@ -647,7 +686,6 @@
    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;
Main/System/Chat/ChatPlayerOtherCell.cs
@@ -13,19 +13,20 @@
    ChatManager manager { get { return ChatManager.Instance; } }
    public void Refresh(CellView cell)
    {
        if (!manager.TryGetChatData(ChatManager.Instance.nowChatChannel, cell.index, out TalkData data))
        if (!manager.TryGetChatData(ChatManager.Instance.nowChatChannel, cell.index, out TalkData nowData) || nowData == null)
            return;
        avatarCell.InitUI(AvatarHelper.GetAvatarModel((int)data.PlayerID, (int)data.Face, (int)data.PlayerID, data.Job));
        m_ChatBubble.DisplayContent(nowData.Content, true);
        bool hasNewPlayerInfo = manager.TryGetNewPlayerInfoByPlayerID(nowData.PlayerID, out TalkData newPlayerInfo);
        TalkData data = hasNewPlayerInfo ? newPlayerInfo : nowData;
        avatarCell.InitUI(AvatarHelper.GetAvatarModel((int)data.PlayerID, (int)data.Face, (int)data.FacePic, data.Job));
        avatarCell.button.SetListener(() =>
        {
        });
        title.InitUI(data.RealmLV, (int)data.TitleID);
        m_ChatBubble.DisplayContent(data.Content, true);
        int bubbleID = ChatBubbleHelper.GetOtherChatBubbleID(data.Job, (int)data.BubbleBox);
        m_ChatBubble.DisplayBubble(bubbleID, (int)data.PlayerID);
Main/System/Chat/ChatWin.cs
@@ -96,10 +96,12 @@
    protected override void OnPreOpen()
    {
        base.OnPreOpen();
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent += OnBeforePlayerDataInitializeEvent;
        manager.OnChatTabChangeEvent += OnChatTabChange;
        manager.OnUpdateTalkEvent += OnUpdateTalkEvent;
        manager.OnUpdateTalkCacheListEvent += OnUpdateTalkCacheList;
        manager.OnDeleteTalkEvent += OnDeleteTalkEvent;
        manager.OnUpdatePlayerInfoEvent += OnUpdatePlayerInfoEvent;
        scrChatTab.OnRefreshCell += OnRefreshChatTabCell;
        scrWorld.OnGetDynamicSize += OnGetWorldChatDynamicSize;
@@ -126,10 +128,12 @@
    protected override void OnPreClose()
    {
        base.OnPreClose();
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent -= OnBeforePlayerDataInitializeEvent;
        manager.OnChatTabChangeEvent -= OnChatTabChange;
        manager.OnUpdateTalkEvent -= OnUpdateTalkEvent;
        manager.OnUpdateTalkCacheListEvent -= OnUpdateTalkCacheList;
        manager.OnDeleteTalkEvent -= OnDeleteTalkEvent;
        manager.OnUpdatePlayerInfoEvent -= OnUpdatePlayerInfoEvent;
        scrChatTab.OnRefreshCell -= OnRefreshChatTabCell;
        scrWorld.OnGetDynamicSize -= OnGetWorldChatDynamicSize;
@@ -140,6 +144,16 @@
        scrGuild.mScrollRect.onValueChanged.RemoveListener(OnGuildScrollValChange);
        GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent;
        clickScreenOtherSpace.RemoveAllListeners();
    }
    private void OnBeforePlayerDataInitializeEvent()
    {
        CreaterAll(manager.nowChatTab);
    }
    private void OnUpdatePlayerInfoEvent()
    {
        RefreshAll(manager.nowChatChannel, isUpdatePlayerInfo: true);
    }
    private void OnDeleteTalkEvent(ChatChannel channel)
@@ -330,21 +344,21 @@
        return 0;
    }
    private void RefreshAll(ChatChannel type, uint playerId = 0)
    private void RefreshAll(ChatChannel type, uint playerId = 0, bool isUpdatePlayerInfo = false)
    {
        scrChatTab.m_Scorller.RefreshActiveCellViews();
        if (type == ChatChannel.World)
        {
            RefreshChat(type, scrWorld, playerId);
            RefreshChat(type, scrWorld, playerId, isUpdatePlayerInfo);
        }
        else if (type == ChatChannel.Guild)
        {
            RefreshChat(type, scrGuild, playerId);
            RefreshChat(type, scrGuild, playerId, isUpdatePlayerInfo);
        }
    }
    private void RefreshChat(ChatChannel type, ScrollerController scroller, uint playerId = 0)
    private void RefreshChat(ChatChannel type, ScrollerController scroller, uint playerId = 0, bool isUpdatePlayerInfo = false)
    {
        if (!manager.TryGetTalkData(type, out List<TalkData> datas) || datas == null)
            return;
@@ -361,6 +375,11 @@
                float height = GetHeight(talkDataType, data.Content, data.InfoList);
                scroller.m_Scorller.AddHeight(true, height);
                //Debug.Log($"ChatWin AddCell i {i} AddHeight {height}");
            }
            if (isUpdatePlayerInfo)
            {
                scroller.m_Scorller.RefreshActiveCellViews();
            }
        }
        else
Main/System/Message/SysNotifyMgr.cs
@@ -240,10 +240,10 @@
                    ServerTipDetails.ShowMarquee(msg, tipInfoList, order);
                    break;
                case SysNotifyType.ChatChannelWorld:
                    ChatManager.Instance.AddSysData(msg, tipInfoList, ChatChannel.World);
                    ChatManager.Instance.AddSysData(msg, tipInfoList, ChatChannel.World, true);
                    break;
                case SysNotifyType.ChatChannelGuild:
                    ChatManager.Instance.AddSysData(msg, tipInfoList, ChatChannel.Guild);
                    ChatManager.Instance.AddSysData(msg, tipInfoList, ChatChannel.Guild, true);
                    break;
                case SysNotifyType.SysRealmTip:
                    if (OnSysTipEvent != null)