using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Text; using System; using System.Text.RegularExpressions; using Snxxz.UI; using TableConfig; using System.Linq; public class ChatCtrl { #region 单例 private static ChatCtrl _inst = null; public static ChatCtrl Inst { get { if (_inst == null) { _inst = new ChatCtrl(); } return _inst; } } #endregion public int CHAT_INFO_CNT = 50; public const int CHAT_TIP_CNT = 4; public const int CHAT_CELL_CNT = 6; public const int CHAT_INFO_LIMIT = 50; public readonly int BugleItem = 0;//喇叭物品id private static StringBuilder _textBuilder = new StringBuilder(); /// /// 聊天信息 /// private bool _lockUpdate = true; public bool lockUpdate { get { return _lockUpdate; } set { _lockUpdate = value; if (ChatFriend != null && ChatFriend.IsOpen) { ChatFriend.OnSetLock(); } } } private Dictionary> chatDics = new Dictionary>(); private Dictionary chatOpenDics = new Dictionary(); public List chatDisplayList = new List(); #region 私聊 private Dictionary> pteChatDics = new Dictionary>(); public event Action OnPteChatChangeEvent; public event Action 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) { var id = (int)PlayerDatas.Instance.PlayerId + playerId; if (pteChatDics.ContainsKey(id)) { pteChatDics.Remove(id); if (OnRefreshPteChat != null) { OnRefreshPteChat(null); } } } public void SelectRecentlyChat(int playerId) { if (SelectRecentlyEvent != null) { SelectRecentlyEvent(playerId); } } #endregion private List chatlist = new List(); private List chatUpList = new List(); 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; } public event Action OnClickCloseChatEvent; public event Action OnChatExtentOpenEvent; public event Action chatFloatUpdate; TeamModel teamModel { get { return ModelCenter.Instance.GetModel(); } } ChatCenter m_ChatCenter; ChatCenter chatCenter { get { return m_ChatCenter ?? (m_ChatCenter = ModelCenter.Instance.GetModel()); } } public Dictionary> achievementRandoms = new Dictionary>(); private ChatCtrl() { chatOpenDics.Add(ChatInfoType.System, true); chatOpenDics.Add(ChatInfoType.World, 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); lockUpdate = true; presentChatType = ChatInfoType.World; IsExtentOpen = false; var _funcCfg = Config.Instance.Get("BugleItem"); BugleItem = int.Parse(_funcCfg.Numerical1); DTC0102_tagCDBPlayer.switchAccountEvent += SwitchAccountEvent; StageManager.Instance.onStageLoadFinish += OnStageLoadFinish; FuncConfigConfig _cfg = Config.Instance.Get("RandomWord"); try { achievementRandoms.Add(ChatInfoType.World, new List(ConfigParse.GetMultipleStr(_cfg.Numerical1))); achievementRandoms.Add(ChatInfoType.Fairy, new List(ConfigParse.GetMultipleStr(_cfg.Numerical2))); } catch (Exception e) { DebugEx.LogError(e.Message); } } private void OnStageLoadFinish() { bool isDungeon = StageManager.Instance.CurrentStage is DungeonStage; if (!isDungeon) { ClearAllChatInfo(); } } private void SwitchAccountEvent() { ClearAllChatInfo(); } public void SendChatInfo(ChatInfoType type, string msg, ChatExtraData? info = null) { bool _dirty = false; if (!ChatCenter.s_VoiceRegex.IsMatch(msg)) { _dirty = DirtyWordConfig.IsDirtWord(msg); msg = DirtyWordConfig.IsDirtWord(msg, '*'); var length = msg.Length; if (length > CHAT_INFO_CNT) { MessageWin.Inst.ShowFixedTip(Language.Get("L1014")); return; } } ChatCenter.RecentlyChat _recentlyChat = null; if (!_dirty) { _recentlyChat = chatCenter.SaveRecentlyChat(msg); } msg = CheckHasItem(msg, _recentlyChat); chatCenter.recentlyChat = null; 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.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.Invite: { SendInvite(msg); } break; } } /// /// 世界频道 /// /// public void RevChatInfo(H0201_tagTalkGong vNetData) { ChatData chatData = null; if (IsInviteChat(vNetData.Content)) { string content = InviteRegex.Replace(vNetData.Content, ""); if (teamModel.myTeam.GetIndexOfMember((int)vNetData.PlayerID) != -1) { content = StringUtility.Contact("", vNetData.Name, "", ":", content); } else { content = StringUtility.Contact("", vNetData.Name, "", ":", content, string.Format("{0}|invite={1}", Language.Get("L1013"), vNetData.PlayerID)); } chatData = new ChatInviteData(content, (int)vNetData.PlayerID, vNetData.Name, vNetData.Extras); KeepChatInfo(chatData); return; } chatData = new ChatWorldData(vNetData.Content, (int)vNetData.PlayerID, vNetData.Name, vNetData.Extras); KeepChatInfo(chatData); } /// /// 区域频道 /// /// public void RevChatInfo(H0207_tagTalkArea vNetData) { ChatData chatData = new ChatAreaData(vNetData.Content, (int)vNetData.PlayerID, vNetData.SrcName, vNetData.Extras); KeepChatInfo(chatData); } /// /// 喇叭喊话 /// /// public void RevChatInfo(HA9A3_tagGCPYSpeakerContent vNetData) { ChatData chatData = new ChatTrumpetData(vNetData.Text, (int)vNetData.PlayerID, vNetData.Name, vNetData.Extras, vNetData.SpeakerType, vNetData.AccID); KeepChatInfo(chatData); ServerTipDetails.ShowTrumpetTip(chatData as ChatTrumpetData); } /// /// 家族频道 /// /// public void RevChatInfo(H0203_tagTalkBang vNetData) { ChatData chatData = new ChatFamilyData(vNetData.Content, (int)vNetData.PlayerID, vNetData.Name, vNetData.Extras); KeepChatInfo(chatData); } /// /// 好友私聊 /// /// 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); if (chatData.player == PlayerDatas.Instance.baseData.PlayerID) { if (OnRefreshSelf != null) { OnRefreshSelf(chatData); } } } private void AddPteChat(ChatFriendData chatData) { List 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); } else { list = new List(); list.Add(chatData); pteChatDics.Add(chatData.player + chatData.toPlayer, list); } if (OnRefreshPteChat != null) OnRefreshPteChat(chatData); } /// /// 队伍频道 /// /// public void RevChatInfo(H0205_tagTalkDui vNetData) { ChatData chatData = new ChatTeamData(vNetData.Content, (int)vNetData.PlayerID, vNetData.Name, vNetData.Extras); KeepChatInfo(chatData); } /// /// GM /// /// public void RevChatInfo(H3202_tagServerResponse vNetData) { ChatData chatData = new ChatSystemData(vNetData.Message); KeepChatInfo(chatData); } /// /// 系统提示 /// /// 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; } if (chatData != null) KeepChatInfo(chatData); } /// /// 获取频道聊天数据 /// /// /// public List GetChatInfo(ChatInfoType type) { List list = null; chatDics.TryGetValue(type, out list); return list; } /// /// 获取好友聊天数据 /// /// /// public List GetChatInfo(int player) { List list = null; pteChatDics.TryGetValue(player + (int)PlayerDatas.Instance.baseData.PlayerID, out list); return list; } /// /// 获取主界面的聊天数据 /// /// public List GetChatInfo() { return chatlist; } public List GetChatUpInfo() { return chatUpList; } public ChatData GetChatInfo(ChatInfoType type, int index) { List list = null; chatDics.TryGetValue(type, out list); if (list != null) { return list[index]; } return null; } private void KeepChatInfo(ChatData data) { KeepAllTypeChat(data); List 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(); 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.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 (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; string[] strarray = detail.Split('|'); int itemID = 0; if (int.TryParse(strarray[0], out itemID)) { ItemConfig cfg = Config.Instance.Get(itemID); if (cfg != null) { string append = string.Format("|showitem={1} isbind={2} itemcnt={3} stone={4} userdata={5} suitLv={6} suitCnt={7} place={8} equipwash={9}", cfg.ItemColor, strarray[0], strarray[1], strarray[2], strarray[3], strarray[4], strarray[5], strarray[6], strarray[7], strarray[8]); append = UIHelper.GetTextColorByItemColor(cfg.ItemColor, append); data.richText.Append(append); } } 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 GetChatOpen() { return chatOpenDics; } #region 组队邀请 private const string INVITE_IDENTIFY = ""; private 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 itemPlaceList = new List(); public bool IsItemChat(string msg) { return HrefAnalysis.EquipDetailRegex.IsMatch(msg); } public string CheckHasItem(string msg,ChatCenter.RecentlyChat _recently) { if (!HrefAnalysis.EquipRegex.IsMatch(msg)) { return msg; } _textBuilder.Length = 0; MatchCollection matchArray = HrefAnalysis.EquipRegex.Matches(msg); int index = 0; for (int i = 0; i < matchArray.Count; i++) { _textBuilder.Append(msg.Substring(index, matchArray[i].Index - index)); if (chatCenter.recentlyChat != null) { if (i < chatCenter.recentlyChat.itemIndexs.Count) { var _index = chatCenter.recentlyChat.itemIndexs[i]; _textBuilder.Append(chatCenter.recentlyChat.itemInfos[_index]); } index = matchArray[i].Index + matchArray[i].Length; continue; } var _length = _textBuilder.Length; if (i < itemPlaceList.Count) { ItemConfig cfg = Config.Instance.Get((int)itemPlaceList[i].itemInfo.ItemID); if (cfg.ItemName == matchArray[i].Groups[1].Value) { bool equip = itemPlaceList[i].packType == PackType.rptEquip; uint[] stones = equip ? PlayerStoneData.Instance.GetStoneInfo(itemPlaceList[i].itemInfo.ItemPlace) : null; _textBuilder.Append(StringUtility.Contact("*", itemPlaceList[i].itemInfo.ItemID, "|", itemPlaceList[i].itemInfo.IsBind, "|", itemPlaceList[i].itemInfo.ItemCount, "|", stones != null ? LitJson.JsonMapper.ToJson(stones) : LitJson.JsonMapper.ToJson(new uint[0]), "|")); if (itemPlaceList[i].useDataDict != null && itemPlaceList[i].useDataDict.Count > 0) { foreach (int key in itemPlaceList[i].useDataDict.Keys) { List intarray = itemPlaceList[i].useDataDict[key]; var _array = intarray.ToArray(); _textBuilder.Append(StringUtility.Contact("'", key, "':", _array != null ? LitJson.JsonMapper.ToJson(_array) : LitJson.JsonMapper.ToJson(new int[0]))); _textBuilder.Append(","); } } _textBuilder.Append("|"); var _dictSuitLv = ModelCenter.Instance.GetModel().GetServerSuitModelByPlace(itemPlaceList[i].itemInfo.ItemPlace); if (_dictSuitLv != null&& equip) { foreach (int key in _dictSuitLv.Keys) { _textBuilder.Append(StringUtility.Contact("'", key, "_", _dictSuitLv[key])); } } _textBuilder.Append("|"); var _dictSuitCnt = ModelCenter.Instance.GetModel().GetServerSuitCntByPlace(itemPlaceList[i].itemInfo.ItemPlace); if (_dictSuitCnt != null && equip) { foreach (int key in _dictSuitCnt.Keys) { _textBuilder.Append(StringUtility.Contact("'", key, "_", _dictSuitCnt[(SuitType)key])); } } _textBuilder.Append("|"); _textBuilder.Append(itemPlaceList[i].itemInfo.ItemPlace); _textBuilder.Append("|"); var _wash = ModelCenter.Instance.GetModel().GetWashEquipInfo(itemPlaceList[i].itemInfo.ItemPlace); if (_wash != null && equip) { _textBuilder.Append("{"); int[] _array = _wash.proValuelist == null ? new int[0] : new int[_wash.proValuelist.Length]; for (int k = 0; k < _array.Length; k++) { _array[k] = (int)_wash.proValuelist[k].XLAttrValue; } _textBuilder.Append(StringUtility.Contact("\"LV\":", _wash.XLAttrLV, ",\"Place\":", _wash.EquipPlace, ",\"Value\":", LitJson.JsonMapper.ToJson(_array))); _textBuilder.Append("}"); } _textBuilder.Append("*"); if (_recently != null) { _recently.Add(cfg.ItemName, _textBuilder.ToString().Substring(_length)); } } else { _textBuilder.Append(matchArray[i].Value); } } else { _textBuilder.Append(matchArray[i].Value); } index = matchArray[i].Index + matchArray[i].Length; } _textBuilder.Append(msg.Substring(index, msg.Length - index)); return _textBuilder.ToString(); } #endregion #region 好友私聊 public const string KILL_IDENTIFY = ""; 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 /// /// 清屏 /// public void ClearAllChatInfo() { chatDics.Clear(); chatlist.Clear(); chatUpList.Clear(); if (OnRefreshChat != null) { OnRefreshChat(presentChatType); } } public void ClearChatInfo(ChatInfoType type) { List 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() { if (OnClickCloseChatEvent != null) { OnClickCloseChatEvent(); } } public bool IsExtentOpen { get; set; } public void OpenChatExtent(bool open) { if (OnChatExtentOpenEvent != null) { 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); } #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.FightPoint); } case ChatInfoType.Fairy: return Language.Get(realmRandomChats[_index]); } return string.Empty; } #endregion #region 宝石炫耀跳转 public bool openFromGem { get; set; } public int flauntGemId { get; set; } public bool flauntGemBind { get; set; } public string GetGemFlauntChat() { var config = Config.Instance.Get(flauntGemId); if (config != null) { ItemModel _item = new ItemModel(PackType.rptItem); ItemInfo _itemInfo = new ItemInfo(); _itemInfo.ItemID = flauntGemId; _itemInfo.IsBind = flauntGemBind ? 1 : 0; _item.SetItemModel(_itemInfo); _item.itemId = flauntGemId; var itemInfo = string.Format("[{0}]", config.ItemName); itemPlaceList.Add(_item); return Language.Get("GemLookTalk", itemInfo); } return string.Empty; } #endregion } public struct ChatExtraData { public int infoint1; public ChatExtraData(int info1) { this.infoint1 = info1; } public static ChatExtraData Default { get { return new ChatExtraData(0); } } } public enum ChatInfoType { System,//系统消息 World, //世界频道 Area, //区域频道 Team, //队伍 Invite,//组队 Trumpet,//喇叭 Fairy,//仙盟 Friend,//私聊 FairyQuestion, FairyTip, TeamTip, }