using System;  
 | 
using System.Collections;  
 | 
using System.Collections.Generic;  
 | 
using System.Text;  
 | 
using System.Text.RegularExpressions;  
 | 
using UnityEngine;  
 | 
  
 | 
namespace Snxxz.UI  
 | 
{  
 | 
      
 | 
    public class ChatCenter : Model, IBeforePlayerDataInitialize, IPlayerLoginOk, ISwitchAccount  
 | 
    {  
 | 
        RealmModel realmModel { get { return ModelCenter.Instance.GetModel<RealmModel>(); } }  
 | 
        public override void Init()  
 | 
        {  
 | 
            ParseConfig();  
 | 
            //var _uiframe = UIFrameMgr.Inst;  
 | 
            SpeechTranslate.Instance.translateResultEvent += TranslateResultEvent;  
 | 
            VoiceWarehouse.voiceRecoderEvent += VoiceRecoderEvent;  
 | 
            SDKUtility.Instance.OnNetworkStatusChanged += OnNetStatusChanged;  
 | 
            ChatSetting.Instance.RefreshChatSetAct += RefreshChatSetAct;  
 | 
            WindowCenter.Instance.windowAfterCloseEvent += WindowAfterCloseEvent;  
 | 
            var httpRequest = VoiceHttpRequest.Instance;  
 | 
            TimeMgr.Instance.OnSyntonyEvent += OnSyntonyEvent;  
 | 
            VoiceHttpRequest.Instance.samplesDecodecComplete += SamplesDecodecComplete;  
 | 
            WindowCenter.Instance.windowAfterOpenEvent += 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 override 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);  
 | 
  
 | 
            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];  
 | 
  
 | 
            config = FuncConfigConfig.Get("LocalChatHistoryCount");  
 | 
            if (config != null)  
 | 
            {  
 | 
                LocalChatHistory.localSaveCount = int.Parse(config.Numerical1);  
 | 
                if (!string.IsNullOrEmpty(config.Numerical2))  
 | 
                {  
 | 
                    LocalChatHistory.localChatKeepHour = 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 = ChatCtrl.Inst.GetChatInfo(_pteChatId == 0 ? ChatCtrl.Inst.PteChatID : _pteChatId);  
 | 
                if (_list == null || _index >= _list.Count)  
 | 
                {  
 | 
                    return null;  
 | 
                }  
 | 
                chat = _list[_index];  
 | 
            }  
 | 
            else  
 | 
            {  
 | 
                List<ChatData> _list = ChatCtrl.Inst.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 (ChatCtrl.Inst.IsInviteChat(_chat)  
 | 
                || Regex.IsMatch(_chat, ChatCtrl.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();  
 | 
            autoPlayVoices.Clear();  
 | 
            voicePlaying = false;  
 | 
        }  
 | 
  
 | 
        public void OnSwitchAccount()  
 | 
        {  
 | 
            ClearAllVoice();  
 | 
        }  
 | 
  
 | 
        private void OnStageLoadFinish()  
 | 
        {  
 | 
            bool isDungeon = StageLoad.Instance.currentStage is DungeonStage;  
 | 
            if (!isDungeon)  
 | 
            {  
 | 
                ClearAllVoice();  
 | 
                openChatAfterCollect = false;  
 | 
            }  
 | 
            if (PlayerDatas.Instance.baseData.MapID != 31230)  
 | 
            {  
 | 
                openChatAfterCollect = false;  
 | 
            }  
 | 
            if (!beforeDungeon && isDungeon)  
 | 
            {  
 | 
                LocalChatHistory.Read();  
 | 
            }  
 | 
            //if (beforeDungeon && !isDungeon)  
 | 
            //{  
 | 
            //    LocalChatHistory.Save();  
 | 
            //}  
 | 
            beforeDungeon = isDungeon;  
 | 
        }  
 | 
  
 | 
        void ClearAllVoice()  
 | 
        {  
 | 
            speechDict.Clear();  
 | 
            requestSpeechTime.Clear();  
 | 
        }  
 | 
  
 | 
        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;  
 | 
            }  
 | 
        }  
 | 
  
 | 
        #region 语音聊天  
 | 
        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);  
 | 
            }  
 | 
        }  
 | 
  
 | 
        private void VoiceRecoderEvent(int _instance)  
 | 
        {  
 | 
            VoiceChat _chat;  
 | 
            byte[] _encode;  
 | 
            if (m_VoiceChatDict.TryGetValue(_instance, out _chat)  
 | 
                && VoiceWarehouse.TryGetVoice(_instance, out _encode))  
 | 
            {  
 | 
                if (_chat.translate)  
 | 
                {  
 | 
                    m_VoiceChatDict.Remove(_instance);  
 | 
                    SendSpeech(_encode, _chat.tick, IsClientBan(_chat.chatType));  
 | 
                }  
 | 
                else  
 | 
                {  
 | 
                    _chat.encode = _encode;  
 | 
                }  
 | 
            }  
 | 
        }  
 | 
  
 | 
        private void TranslateResultEvent(int _instance, bool isOk, string _result)  
 | 
        {  
 | 
            VoiceChat _chat;  
 | 
            if (m_VoiceChatDict.TryGetValue(_instance, out _chat))  
 | 
            {  
 | 
                if (!isOk)  
 | 
                {  
 | 
                    _result = string.Empty;  
 | 
                }  
 | 
                if (_chat.chatType == ChatInfoType.Fairy)  
 | 
                {  
 | 
                    var model = ModelCenter.Instance.GetModel<DailyQuestModel>();  
 | 
                    if (model.GetQuestState((int)DailyQuestType.FairyFeast) == DailyQuestModel.DailyQuestState.Normal  
 | 
                        && PlayerDatas.Instance.baseData.MapID == 31230)  
 | 
                    {  
 | 
                        _result = Regex.Replace(_result, "[\x00-\x2F]|[\x3A-\x40]|[\x5B-\x60]|[\x7B-\x7E]", string.Empty);  
 | 
                        _result = _result.Replace("。", string.Empty);  
 | 
                        _result = _result.Replace(",", string.Empty);  
 | 
                        _result = _result.Replace(";", string.Empty);  
 | 
                        _result = _result.Replace("、", string.Empty);  
 | 
                        _result = _result.Replace("?", string.Empty);  
 | 
                    }  
 | 
                }  
 | 
                if (DirtyWordConfig.IsDirtWord(_result))  
 | 
                {  
 | 
                    _result = DirtyWordConfig.IsDirtWord(_result, '*');  
 | 
                }  
 | 
                if (_chat.chatType != ChatInfoType.World && _chat.chatType != ChatInfoType.Area  
 | 
                    && _chat.chatType != ChatInfoType.Fairy && _chat.chatType != ChatInfoType.Friend  
 | 
                    && _chat.chatType != ChatInfoType.Team && _chat.chatType != ChatInfoType.CrossServer)  
 | 
                {  
 | 
                    m_VoiceChatDict.Remove(_instance);  
 | 
                    return;  
 | 
                }  
 | 
                _chat.translate = true;  
 | 
                _chat.result = _result;  
 | 
                _result = StringUtility.Contact("<v=", _chat.tick, "_", _chat.length, ">", _chat.result);  
 | 
                if (_chat.chatType == ChatInfoType.Friend)  
 | 
                {  
 | 
                    if (_chat.toPlayer != 0)  
 | 
                    {  
 | 
                        ChatExtraData _info = ChatExtraData.Default;  
 | 
                        _info.infoint1 = _chat.toPlayer;  
 | 
                        ChatCtrl.Inst.SendChatInfo(_chat.chatType, _result, _info);  
 | 
                    }  
 | 
                }  
 | 
                else  
 | 
                {  
 | 
                    ChatCtrl.Inst.SendChatInfo(_chat.chatType, _result);  
 | 
                }  
 | 
                if (null != _chat.encode)  
 | 
                {  
 | 
                    SendSpeech(_chat.encode, _chat.tick, IsClientBan(_chat.chatType));  
 | 
                    m_VoiceChatDict.Remove(_instance);  
 | 
                }  
 | 
            }  
 | 
        }  
 | 
  
 | 
        const string downloadUrl = "http://{0}.voice.secondworld.net.cn:53001/voice/download";  
 | 
        private void SendSpeech(byte[] encode, long _tick, bool clientBan)  
 | 
        {  
 | 
            if (IsChatBanned || clientBan)  
 | 
            {  
 | 
                SaveSpeech((int)PlayerDatas.Instance.PlayerId, _tick, encode);  
 | 
                return;  
 | 
            }  
 | 
            VoiceHttpRequest.Instance.Enqueue(encode, _tick, (int)PlayerDatas.Instance.PlayerId);  
 | 
        }  
 | 
  
 | 
        public void DownloadSpeech(int _playerId, long _tick)  
 | 
        {  
 | 
            Dictionary<string, string> dict = new Dictionary<string, string>();  
 | 
            dict.Add("voiceID", _tick.ToString());  
 | 
            dict.Add("playerID", _playerId.ToString());  
 | 
            dict.Add("appid", string.Empty);  
 | 
            dict.Add("content", string.Empty);  
 | 
            HttpRequest.Instance.RequestHttpPost(string.Format(downloadUrl, VersionConfig.Get().appId), dict, HttpRequest.defaultHttpContentType, 3, (bool isOk, string _result) =>  
 | 
               {  
 | 
                   if (isOk)  
 | 
                   {  
 | 
                       try  
 | 
                       {  
 | 
                           var speech = LitJson.JsonMapper.ToObject<HttpSpeech>(_result);  
 | 
                           var tick = long.Parse(speech.voiceID);  
 | 
                           var _player = int.Parse(speech.playerID);  
 | 
                           if (string.IsNullOrEmpty(speech.content))  
 | 
                           {  
 | 
                               var seconds = (TimeUtility.ServerNow - TimeUtility.ClientOriginalTime.AddTicks(_tick)).TotalSeconds;  
 | 
                               if (seconds < 10 && seconds >= 0)//可能是语音未上传成功  
 | 
                               {  
 | 
                                   if (!CheckAutoRequestInDelay(tick, _player))  
 | 
                                   {  
 | 
                                       AutoPlayVoice();  
 | 
                                   }  
 | 
                               }  
 | 
                               else  
 | 
                               {  
 | 
                                   if (autoPlayVoices.Count > 0  
 | 
                                      && autoPlayVoices[0].playerId == _player  
 | 
                                      && autoPlayVoices[0].tick == tick)  
 | 
                                   {  
 | 
                                       RemoveAutoVoice(autoPlayVoices[0].playerId, autoPlayVoices[0].tick);  
 | 
                                       AutoPlayVoice();  
 | 
                                   }  
 | 
                                   else  
 | 
                                   {  
 | 
                                       SysNotifyMgr.Instance.ShowTip("VoiceOutTime");  
 | 
                                   }  
 | 
                               }  
 | 
                               return;  
 | 
                           }  
 | 
                           var bytes = Convert.FromBase64String(speech.content);  
 | 
                           SaveSpeech(_player, tick, bytes);  
 | 
                       }  
 | 
                       catch (Exception e)  
 | 
                       {  
 | 
                           DebugEx.LogError(e.Message);  
 | 
                       }  
 | 
                   }  
 | 
               });  
 | 
        }  
 | 
  
 | 
        private bool CheckAutoRequestInDelay(long tick, int playerId)  
 | 
        {  
 | 
            var autoPlayVoice = autoPlayVoices.Find((x) =>  
 | 
            {  
 | 
                return x.tick == tick && x.playerId == playerId;  
 | 
            });  
 | 
            var seconds = 0f;  
 | 
            if (!autoPlayVoice.Equals(default(VoiceInfo)))  
 | 
            {  
 | 
                seconds = (float)(TimeUtility.ServerNow - autoPlayVoice.lastRequestTime).TotalSeconds;  
 | 
            }  
 | 
            if (seconds < 2f && seconds > 0)  
 | 
            {  
 | 
                TimeMgr.Instance.Register(TimeMgr.SyntonyType.AutoPlayVoice, 2 - seconds, () =>  
 | 
                  {  
 | 
                      AutoPlayVoice();  
 | 
                  });  
 | 
            }  
 | 
            return seconds < 2f && seconds > 0;  
 | 
        }  
 | 
  
 | 
        private bool CheckRequestTimeLimit(int _playerId, long _tick)  
 | 
        {  
 | 
            AudioClip _clip = null;  
 | 
            if (TryGetSpeech(_playerId, _tick, out _clip))  
 | 
            {  
 | 
                return false;  
 | 
            }  
 | 
            Dictionary<long, DateTime> dict = null;  
 | 
            if (!requestSpeechTime.TryGetValue(_playerId, out dict))  
 | 
            {  
 | 
                dict = new Dictionary<long, DateTime>();  
 | 
                requestSpeechTime.Add(_playerId, dict);  
 | 
            }  
 | 
            if (dict.ContainsKey(_tick) &&  
 | 
                (DateTime.Now - dict[_tick]).TotalSeconds < 3.0f)  
 | 
            {  
 | 
                return true;  
 | 
            }  
 | 
            dict[_tick] = DateTime.Now;  
 | 
            return false;  
 | 
        }  
 | 
  
 | 
        private Dictionary<int, Dictionary<long, DateTime>> requestSpeechTime = new Dictionary<int, Dictionary<long, DateTime>>();  
 | 
  
 | 
        Dictionary<int, Dictionary<long, AudioClip>> speechDict = new Dictionary<int, Dictionary<long, AudioClip>>();  
 | 
        public event Action<int, long> speechDownloadSuccess;  
 | 
  
 | 
        private void SaveSpeech(int _playerId, long _tick, byte[] encode)  
 | 
        {  
 | 
            VoiceCodec.Decode(encode, (float[] samples) =>  
 | 
             {  
 | 
                 VoiceHttpRequest.Instance.Enqueue(samples, _tick, _playerId);  
 | 
             });  
 | 
        }  
 | 
  
 | 
        private void SamplesDecodecComplete(VoiceHttpRequest.VoiceDecodec _decodec)  
 | 
        {  
 | 
            Dictionary<long, AudioClip> dict = null;  
 | 
            if (!speechDict.TryGetValue(_decodec.playerId, out dict))  
 | 
            {  
 | 
                dict = new Dictionary<long, AudioClip>();  
 | 
                speechDict.Add(_decodec.playerId, dict);  
 | 
            }  
 | 
            if (dict.ContainsKey(_decodec.tick))  
 | 
            {  
 | 
                return;  
 | 
            }  
 | 
            var clip = AudioClip.Create("Sound", _decodec.samples.Length, 1, VoiceSettings.frequency, false);  
 | 
            clip.SetData(_decodec.samples, 0);  
 | 
            dict.Add(_decodec.tick, clip);  
 | 
            if (_decodec.playerId == cachePlayerId && cacheTick == _decodec.tick)  
 | 
            {  
 | 
                cachePlayerId = 0;  
 | 
                cacheTick = 0;  
 | 
                PlaySpeech(clip, cacheLength);  
 | 
                RemoveAutoVoice(_decodec.playerId, _decodec.tick);  
 | 
            }  
 | 
            else if (autoPlayVoices.Count > 0)  
 | 
            {  
 | 
                AutoPlayVoice();  
 | 
            }  
 | 
            if (speechDownloadSuccess != null)  
 | 
            {  
 | 
                speechDownloadSuccess(_decodec.playerId, _decodec.tick);  
 | 
            }  
 | 
        }  
 | 
  
 | 
        public bool TryGetSpeech(int _playerId, long _tick, out AudioClip _clip)  
 | 
        {  
 | 
            Dictionary<long, AudioClip> _dict = null;  
 | 
            if (speechDict.TryGetValue(_playerId, out _dict))  
 | 
            {  
 | 
                if (_dict.ContainsKey(_tick))  
 | 
                {  
 | 
                    _clip = _dict[_tick];  
 | 
                    return true;  
 | 
                }  
 | 
            }  
 | 
            _clip = null;  
 | 
            return false;  
 | 
        }  
 | 
  
 | 
        private int cachePlayerId = 0;  
 | 
        private long cacheTick = 0;  
 | 
        private float cacheLength = 0;  
 | 
        public void PlaySpeech(int _playerId, long _tick, float _length)  
 | 
        {  
 | 
            if (CheckRequestTimeLimit(_playerId, _tick))  
 | 
            {  
 | 
                return;  
 | 
            }  
 | 
            AudioClip _clip = null;  
 | 
            if (TryGetSpeech(_playerId, _tick, out _clip))  
 | 
            {  
 | 
                PlaySpeech(_clip, _length);  
 | 
                cachePlayerId = 0;  
 | 
                cacheTick = 0;  
 | 
                cacheLength = 0;  
 | 
            }  
 | 
            else  
 | 
            {  
 | 
                cachePlayerId = _playerId;  
 | 
                cacheTick = _tick;  
 | 
                cacheLength = _length;  
 | 
                DownloadSpeech(_playerId, _tick);  
 | 
            }  
 | 
        }  
 | 
  
 | 
        public void PlaySpeech(AudioClip _clip, float _length)  
 | 
        {  
 | 
            SoundPlayer.Instance.mute = true;  
 | 
            _length = Mathf.Max(1.0f, _length);  
 | 
            voicePlaying = true;  
 | 
            TimeMgr.Instance.Register(TimeMgr.SyntonyType.Audio, _length);  
 | 
            SoundPlayer.Instance.PlayAudio(_clip);  
 | 
        }  
 | 
  
 | 
        private void OnSyntonyEvent(TimeMgr.SyntonyType _type)  
 | 
        {  
 | 
            if (_type == TimeMgr.SyntonyType.Audio)  
 | 
            {  
 | 
                SoundPlayer.Instance.mute = false;  
 | 
                voicePlaying = false;  
 | 
                AutoPlayVoice();  
 | 
            }  
 | 
        }  
 | 
  
 | 
        public struct HttpSpeech  
 | 
        {  
 | 
            public string voiceID;  
 | 
            public string playerID;  
 | 
            public string content;  
 | 
        }  
 | 
  
 | 
        private void OnNetStatusChanged(NetworkReachability _state)  
 | 
        {  
 | 
            if ((int)SDKUtility.Instance.NetworkType == 0)  
 | 
            {  
 | 
                autoPlayVoices.Clear();  
 | 
            }  
 | 
        }  
 | 
  
 | 
        public bool voicePlaying { get; private set; }  
 | 
        public List<VoiceInfo> autoPlayVoices = new List<VoiceInfo>();  
 | 
  
 | 
        public void CheckAutoPlayVoice(ChatData _chat)  
 | 
        {  
 | 
            var netType = (int)SDKUtility.Instance.NetworkType;  
 | 
#if UNITY_EDITOR  
 | 
            netType = 2;  
 | 
#endif  
 | 
            if (!serverInited)  
 | 
            {  
 | 
                return;  
 | 
            }  
 | 
            if (SystemSetting.Instance.GetSoundVolume() <= 0.01f)  
 | 
            {  
 | 
                return;  
 | 
            }  
 | 
            var _speechChat = _chat as ChatUeseData;  
 | 
            if (null == _speechChat || !_speechChat.IsSound)  
 | 
            {  
 | 
                return;  
 | 
            }  
 | 
            if (_speechChat.player == PlayerDatas.Instance.PlayerId)  
 | 
            {  
 | 
                return;  
 | 
            }  
 | 
            if (!ChatSetting.Instance.GetAutoPlayVoice(_chat.type, netType))  
 | 
            {  
 | 
                return;  
 | 
            }  
 | 
            if (autoPlayVoices.FindIndex((x) =>  
 | 
             {  
 | 
                 return x.playerId == _speechChat.player && x.tick == _speechChat.soundTick;  
 | 
             }) != -1)  
 | 
            {  
 | 
                return;  
 | 
            }  
 | 
            SnxxzGame.Instance.StartCoroutine(Co_AutoPlay(new VoiceInfo()  
 | 
            {  
 | 
                playerId = _speechChat.player,  
 | 
                tick = _speechChat.soundTick,  
 | 
                type = _speechChat.type,  
 | 
                length = _speechChat.soundLength,  
 | 
            }));  
 | 
        }  
 | 
  
 | 
        private void WindowAfterCloseEvent(Window _win)  
 | 
        {  
 | 
            if (_win is LoadingWin)  
 | 
            {  
 | 
                AutoPlayVoice();  
 | 
            }  
 | 
            CheckChatFloatOpen();  
 | 
        }  
 | 
  
 | 
        IEnumerator Co_AutoPlay(VoiceInfo _info)  
 | 
        {  
 | 
            yield return WaitingForSecondConst.WaitMS500;  
 | 
            if (serverInited)  
 | 
            {  
 | 
                autoPlayVoices.Add(_info);  
 | 
                AutoPlayVoice();  
 | 
            }  
 | 
        }  
 | 
  
 | 
        private void AutoPlayVoice()  
 | 
        {  
 | 
            if (voicePlaying || WindowCenter.Instance.IsOpen<LoadingWin>()  
 | 
                || !(StageLoad.Instance.currentStage is DungeonStage))  
 | 
            {  
 | 
                return;  
 | 
            }  
 | 
            if (autoPlayVoices.Count > 0)  
 | 
            {  
 | 
                var _speech = autoPlayVoices[0];  
 | 
                AudioClip _clip;  
 | 
                if (TryGetSpeech(_speech.playerId, _speech.tick, out _clip))  
 | 
                {  
 | 
                    PlaySpeech(_clip, _speech.length);  
 | 
                    autoPlayVoices.RemoveAt(0);  
 | 
                }  
 | 
                else  
 | 
                {  
 | 
                    _speech.lastRequestTime = TimeUtility.ServerNow;  
 | 
                    DownloadSpeech(_speech.playerId, _speech.tick);  
 | 
                }  
 | 
            }  
 | 
        }  
 | 
  
 | 
        private void RefreshChatSetAct(ChatBoolType _type, bool _open)  
 | 
        {  
 | 
            switch (_type)  
 | 
            {  
 | 
                case ChatBoolType.GradVoice4G:  
 | 
                case ChatBoolType.GradVoiceWifi:  
 | 
                    if (!ChatSetting.Instance.GetAutoPlayVoice(ChatInfoType.Fairy, 1)  
 | 
                        && !ChatSetting.Instance.GetAutoPlayVoice(ChatInfoType.Fairy, 2))  
 | 
                    {  
 | 
                        RemoveAutoVoice(ChatInfoType.Fairy);  
 | 
                    }  
 | 
                    break;  
 | 
                case ChatBoolType.PrivatChatVoice4G:  
 | 
                case ChatBoolType.PrivateChatVoiceWifi:  
 | 
                    if (!ChatSetting.Instance.GetAutoPlayVoice(ChatInfoType.Friend, 1)  
 | 
                        && !ChatSetting.Instance.GetAutoPlayVoice(ChatInfoType.Friend, 2))  
 | 
                    {  
 | 
                        RemoveAutoVoice(ChatInfoType.Friend);  
 | 
                    }  
 | 
                    break;  
 | 
                case ChatBoolType.TeamVoice4G:  
 | 
                case ChatBoolType.TeamVoiceWifi:  
 | 
                    if (!ChatSetting.Instance.GetAutoPlayVoice(ChatInfoType.Team, 1)  
 | 
                       && !ChatSetting.Instance.GetAutoPlayVoice(ChatInfoType.Team, 2))  
 | 
                    {  
 | 
                        RemoveAutoVoice(ChatInfoType.Team);  
 | 
                    }  
 | 
                    break;  
 | 
                case ChatBoolType.WorldVoice4G:  
 | 
                case ChatBoolType.WorldVoiceWifi:  
 | 
                    if (!ChatSetting.Instance.GetAutoPlayVoice(ChatInfoType.World, 1)  
 | 
                       && !ChatSetting.Instance.GetAutoPlayVoice(ChatInfoType.World, 2))  
 | 
                    {  
 | 
                        RemoveAutoVoice(ChatInfoType.World);  
 | 
                    }  
 | 
                    break;  
 | 
                case ChatBoolType.AreaVoiceWifi:  
 | 
                case ChatBoolType.AreaVoice4G:  
 | 
                    if (!ChatSetting.Instance.GetAutoPlayVoice(ChatInfoType.Area, 1)  
 | 
                       && !ChatSetting.Instance.GetAutoPlayVoice(ChatInfoType.Area, 2))  
 | 
                    {  
 | 
                        RemoveAutoVoice(ChatInfoType.Area);  
 | 
                    }  
 | 
                    break;  
 | 
            }  
 | 
        }  
 | 
  
 | 
        private void RemoveAutoVoice(int _playerId, long _tick)  
 | 
        {  
 | 
            autoPlayVoices.RemoveAll((x) =>  
 | 
            {  
 | 
                return x.playerId == _playerId && x.tick == _tick;  
 | 
            });  
 | 
        }  
 | 
  
 | 
        private void RemoveAutoVoice(ChatInfoType _type)  
 | 
        {  
 | 
            autoPlayVoices.RemoveAll((x) =>  
 | 
            {  
 | 
                return x.type == _type;  
 | 
            });  
 | 
        }  
 | 
  
 | 
        public class VoiceInfo  
 | 
        {  
 | 
            public int playerId;  
 | 
            public long tick;  
 | 
            public float length;  
 | 
            public ChatInfoType type;  
 | 
            public DateTime lastRequestTime;  
 | 
        }  
 | 
  
 | 
        #endregion  
 | 
  
 | 
        public void OnPlayerLoginOk()  
 | 
        {  
 | 
            serverInited = true;  
 | 
        }  
 | 
  
 | 
        #region 聊天浮动  
 | 
        private void WindowAfterOpenEvent(Window win)  
 | 
        {  
 | 
            CheckChatFloatOpen();  
 | 
            if (win is MainInterfaceWin)  
 | 
            {  
 | 
                SnxxzGame.Instance.StartCoroutine(Co_CheckAfterCollect());  
 | 
            }  
 | 
        }  
 | 
  
 | 
        private void CheckChatFloatOpen()  
 | 
        {  
 | 
            if (WindowCenter.Instance.ExistAnyFullScreenOrMaskWin() && !WindowCenter.Instance.IsOpen<LoadingWin>()  
 | 
                && StageLoad.Instance.currentStage is DungeonStage && !WindowCenter.Instance.IsOpen<TreasureBaseWin>())  
 | 
            {  
 | 
                if (!WindowCenter.Instance.IsOpen<ChatFloatWin>())  
 | 
                {  
 | 
                    WindowCenter.Instance.Open<ChatFloatWin>();  
 | 
                }  
 | 
            }  
 | 
            else  
 | 
            {  
 | 
                if (WindowCenter.Instance.IsOpen<ChatFloatWin>())  
 | 
                {  
 | 
                    WindowCenter.Instance.Close<ChatFloatWin>();  
 | 
                }  
 | 
            }  
 | 
        }  
 | 
        #endregion  
 | 
  
 | 
        #region 仙盟宴会采集完后打开聊天界面  
 | 
        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();  
 | 
        }  
 | 
  
 | 
        IEnumerator Co_CheckAfterCollect()  
 | 
        {  
 | 
            yield return null;  
 | 
            CheckOpenChatAfterCollect();  
 | 
        }  
 | 
  
 | 
        void CheckOpenChatAfterCollect()  
 | 
        {  
 | 
            if (!openChatAfterCollect)  
 | 
            {  
 | 
                return;  
 | 
            }  
 | 
            if (PlayerDatas.Instance.baseData.MapID != 31230)  
 | 
            {  
 | 
                return;  
 | 
            }  
 | 
            if (!WindowCenter.Instance.IsOpen<MainInterfaceWin>()  
 | 
                || WindowCenter.Instance.ExistAnyFullScreenOrMaskWin()  
 | 
                || StageLoad.Instance.isLoading  
 | 
                || NewBieCenter.Instance.inGuiding)  
 | 
            {  
 | 
                return;  
 | 
            }  
 | 
            openChatAfterCollect = false;  
 | 
            if (!WindowCenter.Instance.IsOpen<ChatWin>())  
 | 
            {  
 | 
                ChatCtrl.Inst.presentChatType = ChatInfoType.Fairy;  
 | 
                WindowCenter.Instance.Open<ChatWin>();  
 | 
            }  
 | 
        }  
 | 
        #endregion  
 | 
  
 | 
        #region 聊天黑名单  
 | 
  
 | 
        public string SetChatExtra()  
 | 
        {  
 | 
            var vipLevel = PlayerDatas.Instance.baseData.VIPLv;  
 | 
            var job = PlayerDatas.Instance.baseData.Job;  
 | 
            var bubbleId = PlayerDatas.Instance.baseData.bubbleId;  
 | 
            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:  
 | 
                        ChatCtrl.Inst.RevChatInfo(new H0201_tagTalkGong()  
 | 
                        {  
 | 
                            Content = message,  
 | 
                            Extras = SetChatExtra(),  
 | 
                            PlayerID = playerId,  
 | 
                            Name = playerName,  
 | 
                        });  
 | 
                        break;  
 | 
                    case ChatInfoType.Area:  
 | 
                        ChatCtrl.Inst.RevChatInfo(new H0207_tagTalkArea()  
 | 
                        {  
 | 
                            Content = message,  
 | 
                            Extras = SetChatExtra(),  
 | 
                            PlayerID = playerId,  
 | 
                            SrcName = playerName,  
 | 
                        });  
 | 
                        break;  
 | 
                    case ChatInfoType.CrossServer:  
 | 
                        ChatCtrl.Inst.RevChatInfo(new H0208_tagTalkCountry()  
 | 
                        {  
 | 
                            Content = message,  
 | 
                            Extras = SetChatExtra(),  
 | 
                            PlayerID = playerId,  
 | 
                            Name = playerName,  
 | 
                        });  
 | 
                        break;  
 | 
                    case ChatInfoType.Team:  
 | 
                        ChatCtrl.Inst.RevChatInfo(new H0205_tagTalkDui()  
 | 
                        {  
 | 
                            PlayerID = playerId,  
 | 
                            Name = playerName,  
 | 
                            Content = message,  
 | 
                            Extras = SetChatExtra(),  
 | 
                        });  
 | 
                        break;  
 | 
                    case ChatInfoType.Fairy:  
 | 
                        ChatCtrl.Inst.RevChatInfo(new H0203_tagTalkBang()  
 | 
                        {  
 | 
                            PlayerID = playerId,  
 | 
                            Content = message,  
 | 
                            Extras = SetChatExtra(),  
 | 
                            Name = playerName,  
 | 
                        });  
 | 
                        break;  
 | 
                    case ChatInfoType.Friend:  
 | 
                        ChatCtrl.Inst.RevChatInfo(new H0206_tagTalkMi()  
 | 
                        {  
 | 
                            PlayerID = playerId,  
 | 
                            SrcName = playerName,  
 | 
                            Content = message,  
 | 
                            Extras = SetChatExtra(),  
 | 
                            ToPlayerID = (uint)toPlayer,  
 | 
                            ToName = string.Empty,  
 | 
                            TalkType = 1,  
 | 
                        });  
 | 
                        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;  
 | 
            }  
 | 
        }  
 | 
        #endregion  
 | 
  
 | 
        #region 聊天禁言  
 | 
        public bool clientBanned {  
 | 
            get {  
 | 
                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)  
 | 
        {  
 | 
            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;  
 | 
        }  
 | 
        #endregion  
 | 
    }  
 | 
}  
 | 
  
 |