| using System;  | 
| using System.Collections;  | 
| using System.Collections.Generic;  | 
| using System.Text;  | 
| using System.Text.RegularExpressions;  | 
| using UnityEngine;  | 
|   | 
| namespace vnxbqy.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;  | 
|             ynmbxxjUtil.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);  | 
|             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];  | 
|   | 
|             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  | 
|                      && _chat.chatType != ChatInfoType.default1)  | 
|                 {  | 
|                     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.vncenter.daojmengxvn.com: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)ynmbxxjUtil.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)ynmbxxjUtil.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());  | 
|             }  | 
|         }  | 
|   | 
|         public bool IsShowChatFloat()  | 
|         {  | 
|             if (WindowCenter.Instance.ExistAnyFullScreenOrMaskWin() && !WindowCenter.Instance.IsOpen<LoadingWin>()  | 
|                 && StageLoad.Instance.currentStage is DungeonStage && !WindowCenter.Instance.IsOpen<TreasureBaseWin>())  | 
|                 return true;  | 
|             return false;  | 
|         }  | 
|   | 
|         private void CheckChatFloatOpen()  | 
|         {  | 
|             if (IsShowChatFloat())  | 
|             {  | 
|                 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;  | 
|                     case ChatInfoType.default1:  | 
|                         ChatCtrl.Inst.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;  | 
|             }  | 
|         }  | 
|         #endregion  | 
|   | 
|         #region 聊天禁言  | 
|         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;  | 
|         }  | 
|         #endregion  | 
|     }  | 
| }  | 
|   |