少年修仙传客户端代码仓库
client_linchunjie
2018-08-27 d106f11e7f44c748f595da36e0cdfd54849649e6
System/FindPrecious/FindPreciousModel.cs
@@ -5,663 +5,660 @@
using TableConfig;
using System.Text;
namespace Snxxz.UI
{
    public class FindPreciousModel : Model, IBeforePlayerDataInitialize, IAfterPlayerDataInitialize, IPlayerLoginOk, IMapInitOk, ISwitchAccount
    {
        public const int PREPOSE_SECONDS = 300;
        public const int FINDPRECIOUS_REDPOINTID = 76000;
        Redpoint findPreciousRedpoint = new Redpoint(FINDPRECIOUS_REDPOINTID);
        int m_ViewKillRecordsBoss = 0;
        public int ViewKillRecordsBoss {
            get { return this.m_ViewKillRecordsBoss; }
            set { this.m_ViewKillRecordsBoss = value; }
        }
        Dictionary<int, BossInfo> bossInfos = new Dictionary<int, BossInfo>();
        List<int> bossNotifies = new List<int>();
        int m_CurrentBossNotify = 0;
        public int currentBossNotify {
            get { return m_CurrentBossNotify; }
            private set {
                if (m_CurrentBossNotify != value)
                {
                    m_CurrentBossNotify = value;
                    if (bossRebornNotifyChangeEvent != null)
                    {
                        bossRebornNotifyChangeEvent();
                    }
                }
            }
        }
        public List<DropRecord> bossDropRecords = new List<DropRecord>();
        Dictionary<int, BossSubscribe> bossSubscribes = new Dictionary<int, BossSubscribe>();
        bool serverInited = false;
        public event Action<int> bossSubscribeChangeEvent;
        public event Action preciousDropRecordUpdateEvent;
        public event Action<int> bossInfoUpdateEvent;
        public event Action bossRebornNotifyChangeEvent;
        DungeonModel dungeonModel { get { return ModelCenter.Instance.GetModel<DungeonModel>(); } }
        DemonJarModel demonJarModel { get { return ModelCenter.Instance.GetModel<DemonJarModel>(); } }
        WorldBossModel worldBossModel { get { return ModelCenter.Instance.GetModel<WorldBossModel>(); } }
        BossHomeModel bossHomeModel { get { return ModelCenter.Instance.GetModel<BossHomeModel>(); } }
        PersonalBossModel personalBossModel { get { return ModelCenter.Instance.GetModel<PersonalBossModel>(); } }
        public override void Init()
        {
            DTCA003_tagUniversalGameRecInfo.onGetUniversalGameInfo += OnPreciousDropRecordUpdate;
            FindPreciousTimer.Instance.bossRebornNotifyEvent += OnBossRebornUpComing;
            RedpointCenter.Instance.redpointValueChangeEvent += UpdateRedpoint;
        }
        public override void UnInit()
        {
            DTCA003_tagUniversalGameRecInfo.onGetUniversalGameInfo -= OnPreciousDropRecordUpdate;
            FindPreciousTimer.Instance.bossRebornNotifyEvent -= OnBossRebornUpComing;
            RedpointCenter.Instance.redpointValueChangeEvent -= UpdateRedpoint;
        }
        public void OnBeforePlayerDataInitialize()
        {
            serverInited = false;
        }
        public void OnAfterPlayerDataInitialize()
        {
        }
        public void OnPlayerLoginOk()
        {
            serverInited = true;
            InitializeBossNotify();
        }
        public void OnSwitchAccount()
        {
            m_CurrentBossNotify = 0;
            bossSubscribes.Clear();
            bossNotifies.Clear();
            FindPreciousTimer.Instance.Clear();
        }
        public void OnMapInitOk()
        {
            var mapId = PlayerDatas.Instance.baseData.MapID;
            var mapConfig = ConfigManager.Instance.GetTemplate<MapConfig>(mapId);
            if (mapConfig != null && mapConfig.MapFBType != (int)MapType.OpenCountry)
            {
                bossNotifies.Clear();
                currentBossNotify = GetNextBossNotify();
            }
        }
        public void RequestViewPreciousDropRecord()
        {
            bossDropRecords.Clear();
            var sendInfo = new CA001_tagViewUniversalGameRec();
            sendInfo.ViewType = 25;
            GameNetSystem.Instance.SendInfo(sendInfo);
        }
        public void OnPreciousDropRecordUpdate(HA003_tagUniversalGameRecInfo _serverInfo)
        {
            if (_serverInfo.Type != 25)
            {
                return;
            }
            bossDropRecords.Clear();
            for (int i = 0; i < _serverInfo.Count; i++)
            {
                var serverRecord = _serverInfo.UniversalGameRec[i];
                bossDropRecords.Add(new DropRecord(serverRecord));
            }
            bossDropRecords.Sort(DropRecord.Compare);
            if (bossDropRecords.Count > 5)
            {
                var records1 = new List<DropRecord>();
                for (int i = 0; i < 5; i++)
                {
                    records1.Add(bossDropRecords[i]);
                }
                var records2 = new List<DropRecord>();
                for (int i = 5; i < bossDropRecords.Count; i++)
                {
                    records2.Add(bossDropRecords[i]);
                }
                records2.Sort(DropRecord.Compare2);
                bossDropRecords.Clear();
                bossDropRecords.AddRange(records1);
                bossDropRecords.AddRange(records2);
            }
            for (int i = 0; i < bossDropRecords.Count; i++)
            {
                var record = bossDropRecords[i];
                record.index = i;
                bossDropRecords[i] = record;
            }
            if (preciousDropRecordUpdateEvent != null)
            {
                preciousDropRecordUpdateEvent();
            }
        }
        public void OnUpdateBossInfos(HA902_tagGCGameWorldBossInfo _bossInfo)
        {
            for (int i = 0; i < _bossInfo.BossInfoList.Length; i++)
            {
                var serverBossInfo = _bossInfo.BossInfoList[i];
                var bossId = (int)serverBossInfo.BossID;
                var bossOldAliveState = IsBossAlive(bossId);
                if (!bossInfos.ContainsKey(bossId))
                {
                    bossInfos[bossId] = new BossInfo(bossId);
                }
                bossInfos[bossId].UpdateBossInfo(serverBossInfo);
                var bossNewAliveState = IsBossAlive(bossId);
                if (!IsBossAlive(bossId))
                {
                    RemoveOneBossRebornNotify(bossId);
                }
                else
                {
                    if (bossNewAliveState != bossOldAliveState)
                    {
                        if (ConfigManager.Instance.ContainKey<DemonJarConfig>(bossId))
                        {
                            var config = ConfigManager.Instance.GetTemplate<DemonJarConfig>(bossId);
                            var grade = dungeonModel.GetDungeonGrade(new Dungeon(DemonJarModel.DEMONJAR_MAPID, config.LineID));
                            if ((config.CanEnterTimes == 0 || grade == 0))
                            {
                                AddOneBossRebornNotify(bossId);
                            }
                        }
                        else
                        {
                            if ((bossInfos[bossId].refreshTime - DateTime.Now).TotalSeconds < PREPOSE_SECONDS)
                            {
                                AddOneBossRebornNotify(bossId);
                            }
                            else
                            {
                                FindPreciousTimer.Instance.AddClock(bossId, bossInfos[bossId].refreshTime);
                            }
                        }
                    }
                }
                if (bossInfoUpdateEvent != null)
                {
                    bossInfoUpdateEvent(bossId);
                }
            }
            if (!serverInited)
            {
                personalBossModel.UpdateRedpoint();
            }
        }
        public void OnUpdateBossLineInfos(HA901_tagGCBossShuntLineStateInfo _lineBossInfo)
        {
            for (int i = 0; i < _lineBossInfo.Count; i++)
            {
                var bossLineInfo = _lineBossInfo.BossLineStateInfo[i];
                var bossId = (int)bossLineInfo.BossID;
                BossInfo bossInfo;
                if (TryGetBossInfo(bossId, out bossInfo))
                {
                    bossInfo.deadLines.Clear();
                    bossInfo.deadLines.AddRange(bossLineInfo.DeadLineList);
                }
            }
        }
        public bool TryGetBossInfo(int _bossId, out BossInfo _bossInfo)
        {
            return bossInfos.TryGetValue(_bossId, out _bossInfo);
        }
        public bool IsBossAlive(int _bossId)
        {
            if (demonJarModel.IsPersonalBoss(_bossId))
            {
                return true;
            }
            else
            {
                return bossInfos.ContainsKey(_bossId) && bossInfos[_bossId].IsBossAlive();
            }
        }
        public List<BossKillRecord> GetBossKillRecords(int _bossId)
        {
            if (bossInfos.ContainsKey(_bossId))
            {
                return bossInfos[_bossId].killRecords;
            }
            else
            {
                return null;
            }
        }
        public bool IsBossSubscribed(int _bossId)
        {
            return bossSubscribes.ContainsKey(_bossId)
                && (bossSubscribes[_bossId].subscribeState == 1
                || bossSubscribes[_bossId].subscribeState == 2);
        }
        public bool IsBossAutoSubscribe(int _bossId)
        {
            if (bossSubscribes.ContainsKey(_bossId))
            {
                return bossSubscribes[_bossId].isAutoSubscribe;
            }
            else
            {
                return false;
            }
        }
        public bool IsBossNeverSubscribe(int _bossId)
        {
            return !bossSubscribes.ContainsKey(_bossId);
        }
        public void RequestSubscribeBoss(int _bossId, bool _autoSubscribe)
        {
            var sendInfo = new CA903_tagCGAttentionBoss();
            sendInfo.BossID = (uint)_bossId;
            sendInfo.IsAdd = (byte)(_autoSubscribe ? 2 : 1);
            GameNetSystem.Instance.SendInfo(sendInfo);
            if (!IsBossSubscribed(_bossId))
            {
                bossSubscribes[_bossId] = new BossSubscribe(_bossId, _autoSubscribe ? 2 : 1);
            }
            if (!_autoSubscribe)
            {
                WindowCenter.Instance.Open<FindPreciousSubscribeHintWin>();
            }
            if (bossSubscribeChangeEvent != null)
            {
                bossSubscribeChangeEvent(_bossId);
            }
        }
        public void RequestDeSubscribeBoss(int _bossId)
        {
            var sendInfo = new CA903_tagCGAttentionBoss();
            sendInfo.BossID = (uint)_bossId;
            sendInfo.IsAdd = 0;
            GameNetSystem.Instance.SendInfo(sendInfo);
            if (IsBossSubscribed(_bossId))
            {
                bossSubscribes.Remove(_bossId);
            }
            if (bossSubscribeChangeEvent != null)
            {
                bossSubscribeChangeEvent(_bossId);
            }
        }
        public void OnUpdateBossSubscribe(HA909_tagGCBossAttentionInfo _serverInfo)
        {
            bossSubscribes.Clear();
            for (int i = 0; i < _serverInfo.BossList.Length; i++)
            {
                var info = _serverInfo.BossList[i];
                var bossId = (int)info.BossID;
                bossSubscribes[bossId] = new BossSubscribe(bossId, info.AddState);
            }
        }
        public void AddOneBossRebornNotify(int _bossId)
        {
            if (IsBossSubscribed(_bossId) && !bossNotifies.Contains(_bossId))
            {
                var type = GetBossFindPreciousType(_bossId);
                if (type == FindPreciousType.DemonJar && demonJarModel.GetSurplusTimes() <= 0)
                {
                }
                else
                {
                    bossNotifies.Add(_bossId);
                    currentBossNotify = GetNextBossNotify();
                }
            }
        }
        public void RemoveOneBossRebornNotify(int _bossId)
        {
            if (bossNotifies.Contains(_bossId))
            {
                bossNotifies.Remove(_bossId);
                currentBossNotify = GetNextBossNotify();
            }
        }
        public void ReportConfirmBossRebornNotify(int _bossId)
        {
            if (bossNotifies.Contains(_bossId))
            {
                bossNotifies.Remove(_bossId);
            }
            currentBossNotify = GetNextBossNotify();
        }
        public void RemoveRebornNotifies(FindPreciousType _type)
        {
            for (int i = bossNotifies.Count - 1; i >= 0; i--)
            {
                var bossId = bossNotifies[i];
                if (GetBossFindPreciousType(bossId) == _type)
                {
                    bossNotifies.Remove(bossId);
                }
            }
            currentBossNotify = GetNextBossNotify();
        }
        private void UpdateRedpoint(int _redpointId)
        {
            if (_redpointId == WorldBossModel.WORLDBOSS_REDPOINT ||
                _redpointId == BossHomeModel.BOSSHOME_REDPOINT ||
                _redpointId == PersonalBossModel.PERSONAL_REDPOINTID)
            {
                var count = worldBossModel.worldBossRedPoint.count + bossHomeModel.bossHomeRedpoint.count + personalBossModel.personalRedpoint.count;
                findPreciousRedpoint.state = count > 0 ? RedPointState.Quantity : RedPointState.None;
                findPreciousRedpoint.count = count;
            }
        }
        public FindPreciousType GetBossFindPreciousType(int _bossId)
        {
            if (ConfigManager.Instance.ContainKey<WorldBossConfig>(_bossId))
            {
                return FindPreciousType.WorldBoss;
            }
            else if (ConfigManager.Instance.ContainKey<BossHomeConfig>(_bossId))
            {
                return FindPreciousType.BossHome;
            }
            else if (ConfigManager.Instance.ContainKey<ElderGodAreaConfig>(_bossId))
            {
                return FindPreciousType.ElderGodArea;
            }
            else if (ConfigManager.Instance.ContainKey<DemonJarConfig>(_bossId))
            {
                return FindPreciousType.DemonJar;
            }
            else if (ConfigManager.Instance.ContainKey<PersonalBossConfig>(_bossId))
            {
                return FindPreciousType.PersonalBoss;
            }
            return FindPreciousType.None;
        }
        private int GetNextBossNotify()
        {
            if (bossNotifies.Count > 0)
            {
                return bossNotifies[0];
            }
            else
            {
                return 0;
            }
        }
        private void OnBossRebornUpComing(int _bossId)
        {
            AddOneBossRebornNotify(_bossId);
        }
        private void InitializeBossNotify()
        {
            m_CurrentBossNotify = 0;
            bossNotifies.Clear();
            foreach (var boss in bossInfos.Values)
            {
                var bossId = boss.bossId;
                if (!IsBossAlive(bossId))
                {
                    RemoveOneBossRebornNotify(bossId);
                }
                else
                {
                    if (ConfigManager.Instance.ContainKey<DemonJarConfig>(bossId))
                    {
                        var config = ConfigManager.Instance.GetTemplate<DemonJarConfig>(bossId);
                        var grade = dungeonModel.GetDungeonGrade(new Dungeon(DemonJarModel.DEMONJAR_MAPID, config.LineID));
                        if ((config.CanEnterTimes == 0 || grade == 0))
                        {
                            AddOneBossRebornNotify(bossId);
                        }
                    }
                    else
                    {
                        if ((bossInfos[bossId].refreshTime - DateTime.Now).TotalSeconds < PREPOSE_SECONDS)
                        {
                            AddOneBossRebornNotify(bossId);
                        }
                        else
                        {
                            FindPreciousTimer.Instance.AddClock(bossId, bossInfos[bossId].refreshTime);
                        }
                    }
                }
            }
        }
        public class BossInfo
        {
            public int bossId { get; private set; }
            bool isCommunalAlive { get; set; }
            public List<BossKillRecord> killRecords = new List<BossKillRecord>();
            public DateTime refreshTime { get; private set; }
            public List<byte> deadLines = new List<byte>();
            public BossInfo(int _id)
            {
                bossId = _id;
            }
            public void UpdateBossInfo(HA902_tagGCGameWorldBossInfo.tagBossInfoObj _bossInfo)
            {
                isCommunalAlive = _bossInfo.IsAlive == 1;
                killRecords.Clear();
                if (!string.IsNullOrEmpty(_bossInfo.KillRecord))
                {
                    var recordStrings = _bossInfo.KillRecord.Split('|');
                    for (int i = 0; i < recordStrings.Length; i++)
                    {
                        killRecords.Add(new BossKillRecord(recordStrings[i]));
                    }
                }
                refreshTime = DateTime.Now + new TimeSpan(_bossInfo.RefreshSecond * TimeSpan.TicksPerSecond);
            }
            public bool IsBossAlive()
            {
                if (BossFakeLineUtility.Instance.IsShuntBoss(bossId))
                {
                    if (BossFakeLineUtility.Instance.IsBossVisible(bossId))
                    {
                        return true;
                    }
                    else if (BossFakeLineUtility.Instance.IsBossTombstoneVisble(bossId))
                    {
                        return false;
                    }
                    else if ((BossFakeLineUtility.Instance.lastBossNpcID == bossId && Time.realtimeSinceStartup < BossFakeLineUtility.Instance.inMistakeForBossAliveOverTime)
                        && !IsLineBossDead(PlayerDatas.Instance.baseData.FBID))
                    {
                        return true;
                    }
                    else
                    {
                        return isCommunalAlive;
                    }
                }
                else
                {
                    return isCommunalAlive;
                }
            }
            bool IsLineBossDead(int _lineId)
            {
                return deadLines.Contains((byte)_lineId);
            }
        }
        public struct BossSubscribe
        {
            public int bossId;
            public int subscribeState;
            public bool isAutoSubscribe { get { return this.subscribeState == 2; } }
            public BossSubscribe(int _bossId, int _subscribeState)
            {
                this.bossId = _bossId;
                this.subscribeState = _subscribeState;
            }
        }
        public struct BossKillRecord
        {
            public string playerName;
            public DateTime killTime;
            public long hurt;
            public BossKillRecord(string _record)
            {
                var recordStrings = _record.Split('_');
                killTime = TimeUtility.GetTime(uint.Parse(recordStrings[0]));
                playerName = recordStrings[1];
                hurt = recordStrings.Length > 2 ? long.Parse(recordStrings[2]) : 0;
            }
            public override string ToString()
            {
                return Language.Get("FightTreasure_KillTime", killTime.ToString("HH:mm:ss"), playerName);
            }
        }
        public struct DropRecord
        {
            public int index;
            public DateTime time;
            public string playerName;
            public int mapId;
            public int bossId;
            public int itemId;
            public string userdata;
            public int playerId;
            public int rarility;
            public DropRecord(HA003_tagUniversalGameRecInfo.tagUniversalGameRec _serverInfo)
            {
                this.index = 0;
                this.time = TimeUtility.GetTime(_serverInfo.Time);
                this.playerName = _serverInfo.StrValue1;
                this.mapId = (int)_serverInfo.Value1;
                this.bossId = (int)_serverInfo.Value2;
                this.itemId = (int)_serverInfo.Value3;
                this.userdata = _serverInfo.StrValue3;
                this.playerId = (int)_serverInfo.Value4;
                this.rarility = (int)_serverInfo.Value5;
            }
            public override string ToString()
            {
                var timeString = time.ToString("yyyy-MM-dd HH:mm:ss");
                return Language.Get("FightTreasure_DropRecord", timeString, playerName, playerId, mapId, bossId, itemId, userdata);
            }
            public static int Compare(DropRecord _lhs, DropRecord _rhs)
            {
                var timeStandard = new DateTime(TimeUtility.ServerNow.Year, TimeUtility.ServerNow.Month, TimeUtility.ServerNow.Day, 5, 0, 0);
                if (_lhs.time > timeStandard && _rhs.time < timeStandard)
                {
                    return -1;
                }
                else if (_lhs.time < timeStandard && _rhs.time > timeStandard)
                {
                    return 1;
                }
                else
                {
                    if (_lhs.rarility > _rhs.rarility)
                    {
                        return -1;
                    }
                    else if (_lhs.rarility < _rhs.rarility)
                    {
                        return 1;
                    }
                    else
                    {
                        return _lhs.time > _rhs.time ? -1 : 1;
                    }
                }
            }
            public static int Compare2(DropRecord _lhs, DropRecord _rhs)
            {
                return _lhs.time > _rhs.time ? -1 : 1;
            }
        }
        public enum FindPreciousType
        {
            None,
            WorldBoss,
            BossHome,
            PersonalBoss,
            ElderGodArea,
            DemonJar,
        }
    }
namespace Snxxz.UI
{
    public class FindPreciousModel : Model, IBeforePlayerDataInitialize, IAfterPlayerDataInitialize, IPlayerLoginOk, IMapInitOk, ISwitchAccount
    {
        public const int PREPOSE_SECONDS = 300;
        public const int FINDPRECIOUS_REDPOINTID = 76000;
        Redpoint findPreciousRedpoint = new Redpoint(FINDPRECIOUS_REDPOINTID);
        int m_ViewKillRecordsBoss = 0;
        public int ViewKillRecordsBoss {
            get { return this.m_ViewKillRecordsBoss; }
            set { this.m_ViewKillRecordsBoss = value; }
        }
        Dictionary<int, BossInfo> bossInfos = new Dictionary<int, BossInfo>();
        List<int> bossNotifies = new List<int>();
        int m_CurrentBossNotify = 0;
        public int currentBossNotify {
            get { return m_CurrentBossNotify; }
            private set {
                if (m_CurrentBossNotify != value)
                {
                    m_CurrentBossNotify = value;
                    if (bossRebornNotifyChangeEvent != null)
                    {
                        bossRebornNotifyChangeEvent();
                    }
                }
            }
        }
        public List<DropRecord> bossDropRecords = new List<DropRecord>();
        Dictionary<int, BossSubscribe> bossSubscribes = new Dictionary<int, BossSubscribe>();
        bool serverInited = false;
        public event Action<int> bossSubscribeChangeEvent;
        public event Action preciousDropRecordUpdateEvent;
        public event Action<int> bossInfoUpdateEvent;
        public event Action bossRebornNotifyChangeEvent;
        DungeonModel dungeonModel { get { return ModelCenter.Instance.GetModel<DungeonModel>(); } }
        DemonJarModel demonJarModel { get { return ModelCenter.Instance.GetModel<DemonJarModel>(); } }
        WorldBossModel worldBossModel { get { return ModelCenter.Instance.GetModel<WorldBossModel>(); } }
        BossHomeModel bossHomeModel { get { return ModelCenter.Instance.GetModel<BossHomeModel>(); } }
        PersonalBossModel personalBossModel { get { return ModelCenter.Instance.GetModel<PersonalBossModel>(); } }
        public override void Init()
        {
            DTCA003_tagUniversalGameRecInfo.onGetUniversalGameInfo += OnPreciousDropRecordUpdate;
            FindPreciousTimer.Instance.bossRebornNotifyEvent += OnBossRebornUpComing;
            RedpointCenter.Instance.redpointValueChangeEvent += UpdateRedpoint;
        }
        public override void UnInit()
        {
            DTCA003_tagUniversalGameRecInfo.onGetUniversalGameInfo -= OnPreciousDropRecordUpdate;
            FindPreciousTimer.Instance.bossRebornNotifyEvent -= OnBossRebornUpComing;
            RedpointCenter.Instance.redpointValueChangeEvent -= UpdateRedpoint;
        }
        public void OnBeforePlayerDataInitialize()
        {
            serverInited = false;
        }
        public void OnAfterPlayerDataInitialize()
        {
        }
        public void OnPlayerLoginOk()
        {
            serverInited = true;
            InitializeBossNotify();
        }
        public void OnSwitchAccount()
        {
            m_CurrentBossNotify = 0;
            bossSubscribes.Clear();
            bossNotifies.Clear();
            FindPreciousTimer.Instance.Clear();
        }
        public void OnMapInitOk()
        {
            var mapId = PlayerDatas.Instance.baseData.MapID;
            var mapConfig = Config.Instance.Get<MapConfig>(mapId);
            if (mapConfig != null && mapConfig.MapFBType != (int)MapType.OpenCountry)
            {
                bossNotifies.Clear();
                currentBossNotify = GetNextBossNotify();
            }
        }
        public void RequestViewPreciousDropRecord()
        {
            bossDropRecords.Clear();
            var sendInfo = new CA001_tagViewUniversalGameRec();
            sendInfo.ViewType = 25;
            GameNetSystem.Instance.SendInfo(sendInfo);
        }
        public void OnPreciousDropRecordUpdate(HA003_tagUniversalGameRecInfo _serverInfo)
        {
            if (_serverInfo.Type != 25)
            {
                return;
            }
            bossDropRecords.Clear();
            for (int i = 0; i < _serverInfo.Count; i++)
            {
                var serverRecord = _serverInfo.UniversalGameRec[i];
                bossDropRecords.Add(new DropRecord(serverRecord));
            }
            bossDropRecords.Sort(DropRecord.Compare);
            if (bossDropRecords.Count > 5)
            {
                var records1 = new List<DropRecord>();
                for (int i = 0; i < 5; i++)
                {
                    records1.Add(bossDropRecords[i]);
                }
                var records2 = new List<DropRecord>();
                for (int i = 5; i < bossDropRecords.Count; i++)
                {
                    records2.Add(bossDropRecords[i]);
                }
                records2.Sort(DropRecord.Compare2);
                bossDropRecords.Clear();
                bossDropRecords.AddRange(records1);
                bossDropRecords.AddRange(records2);
            }
            for (int i = 0; i < bossDropRecords.Count; i++)
            {
                var record = bossDropRecords[i];
                record.index = i;
                bossDropRecords[i] = record;
            }
            if (preciousDropRecordUpdateEvent != null)
            {
                preciousDropRecordUpdateEvent();
            }
        }
        public void OnUpdateBossInfos(HA902_tagGCGameWorldBossInfo _bossInfo)
        {
            for (int i = 0; i < _bossInfo.BossInfoList.Length; i++)
            {
                var serverBossInfo = _bossInfo.BossInfoList[i];
                var bossId = (int)serverBossInfo.BossID;
                var bossOldAliveState = IsBossAlive(bossId);
                if (!bossInfos.ContainsKey(bossId))
                {
                    bossInfos[bossId] = new BossInfo(bossId);
                }
                bossInfos[bossId].UpdateBossInfo(serverBossInfo);
                var bossNewAliveState = IsBossAlive(bossId);
                if (!IsBossAlive(bossId))
                {
                    RemoveOneBossRebornNotify(bossId);
                }
                else
                {
                    if (bossNewAliveState != bossOldAliveState)
                    {
                        if (Config.Instance.ContainKey<DemonJarConfig>(bossId))
                        {
                            var config = Config.Instance.Get<DemonJarConfig>(bossId);
                            var grade = dungeonModel.GetDungeonGrade(new Dungeon(DemonJarModel.DEMONJAR_MAPID, config.LineID));
                            if ((config.CanEnterTimes == 0 || grade == 0))
                            {
                                AddOneBossRebornNotify(bossId);
                            }
                        }
                        else
                        {
                            if ((bossInfos[bossId].refreshTime - DateTime.Now).TotalSeconds < PREPOSE_SECONDS)
                            {
                                AddOneBossRebornNotify(bossId);
                            }
                            else
                            {
                                FindPreciousTimer.Instance.AddClock(bossId, bossInfos[bossId].refreshTime);
                            }
                        }
                    }
                }
                if (bossInfoUpdateEvent != null)
                {
                    bossInfoUpdateEvent(bossId);
                }
            }
            if (!serverInited)
            {
                personalBossModel.UpdateRedpoint();
            }
        }
        public void OnUpdateBossLineInfos(HA901_tagGCBossShuntLineStateInfo _lineBossInfo)
        {
            for (int i = 0; i < _lineBossInfo.Count; i++)
            {
                var bossLineInfo = _lineBossInfo.BossLineStateInfo[i];
                var bossId = (int)bossLineInfo.BossID;
                BossInfo bossInfo;
                if (TryGetBossInfo(bossId, out bossInfo))
                {
                    bossInfo.deadLines.Clear();
                    bossInfo.deadLines.AddRange(bossLineInfo.DeadLineList);
                }
            }
        }
        public bool TryGetBossInfo(int _bossId, out BossInfo _bossInfo)
        {
            return bossInfos.TryGetValue(_bossId, out _bossInfo);
        }
        public bool IsBossAlive(int _bossId)
        {
            if (demonJarModel.IsPersonalBoss(_bossId))
            {
                return true;
            }
            else
            {
                return bossInfos.ContainsKey(_bossId) && bossInfos[_bossId].IsBossAlive();
            }
        }
        public List<BossKillRecord> GetBossKillRecords(int _bossId)
        {
            if (bossInfos.ContainsKey(_bossId))
            {
                return bossInfos[_bossId].killRecords;
            }
            else
            {
                return null;
            }
        }
        public bool IsBossSubscribed(int _bossId)
        {
            return bossSubscribes.ContainsKey(_bossId)
                && (bossSubscribes[_bossId].subscribeState == 1
                || bossSubscribes[_bossId].subscribeState == 2);
        }
        public bool IsBossAutoSubscribe(int _bossId)
        {
            if (bossSubscribes.ContainsKey(_bossId))
            {
                return bossSubscribes[_bossId].isAutoSubscribe;
            }
            else
            {
                return false;
            }
        }
        public bool IsBossNeverSubscribe(int _bossId)
        {
            return !bossSubscribes.ContainsKey(_bossId) || bossSubscribes[_bossId].subscribeState == 0;
        }
        public void RequestSubscribeBoss(int _bossId, bool _autoSubscribe)
        {
            var sendInfo = new CA903_tagCGAttentionBoss();
            sendInfo.BossID = (uint)_bossId;
            sendInfo.IsAdd = (byte)(_autoSubscribe ? 2 : 1);
            GameNetSystem.Instance.SendInfo(sendInfo);
            if (!IsBossSubscribed(_bossId))
            {
                bossSubscribes[_bossId] = new BossSubscribe(_bossId, _autoSubscribe ? 2 : 1);
            }
            if (!_autoSubscribe)
            {
                WindowCenter.Instance.Open<FindPreciousSubscribeHintWin>();
            }
            if (bossSubscribeChangeEvent != null)
            {
                bossSubscribeChangeEvent(_bossId);
            }
        }
        public void RequestDeSubscribeBoss(int _bossId)
        {
            var sendInfo = new CA903_tagCGAttentionBoss();
            sendInfo.BossID = (uint)_bossId;
            sendInfo.IsAdd = 0;
            GameNetSystem.Instance.SendInfo(sendInfo);
            bossSubscribes[_bossId] = new BossSubscribe(_bossId, 9);
            if (bossSubscribeChangeEvent != null)
            {
                bossSubscribeChangeEvent(_bossId);
            }
        }
        public void OnUpdateBossSubscribe(HA909_tagGCBossAttentionInfo _serverInfo)
        {
            bossSubscribes.Clear();
            for (int i = 0; i < _serverInfo.BossList.Length; i++)
            {
                var info = _serverInfo.BossList[i];
                var bossId = (int)info.BossID;
                bossSubscribes[bossId] = new BossSubscribe(bossId, info.AddState);
            }
        }
        public void AddOneBossRebornNotify(int _bossId)
        {
            if (IsBossSubscribed(_bossId) && !bossNotifies.Contains(_bossId))
            {
                var type = GetBossFindPreciousType(_bossId);
                if (type == FindPreciousType.DemonJar && demonJarModel.GetSurplusTimes() <= 0)
                {
                }
                else
                {
                    bossNotifies.Add(_bossId);
                    currentBossNotify = GetNextBossNotify();
                }
            }
        }
        public void RemoveOneBossRebornNotify(int _bossId)
        {
            if (bossNotifies.Contains(_bossId))
            {
                bossNotifies.Remove(_bossId);
                currentBossNotify = GetNextBossNotify();
            }
        }
        public void ReportConfirmBossRebornNotify(int _bossId)
        {
            if (bossNotifies.Contains(_bossId))
            {
                bossNotifies.Remove(_bossId);
            }
            currentBossNotify = GetNextBossNotify();
        }
        public void RemoveRebornNotifies(FindPreciousType _type)
        {
            for (int i = bossNotifies.Count - 1; i >= 0; i--)
            {
                var bossId = bossNotifies[i];
                if (GetBossFindPreciousType(bossId) == _type)
                {
                    bossNotifies.Remove(bossId);
                }
            }
            currentBossNotify = GetNextBossNotify();
        }
        private void UpdateRedpoint(int _redpointId)
        {
            if (_redpointId == WorldBossModel.WORLDBOSS_REDPOINT ||
                _redpointId == BossHomeModel.BOSSHOME_REDPOINT ||
                _redpointId == PersonalBossModel.PERSONAL_REDPOINTID)
            {
                var count = worldBossModel.worldBossRedPoint.count + bossHomeModel.bossHomeRedpoint.count + personalBossModel.personalRedpoint.count;
                findPreciousRedpoint.state = count > 0 ? RedPointState.Quantity : RedPointState.None;
                findPreciousRedpoint.count = count;
            }
        }
        public FindPreciousType GetBossFindPreciousType(int _bossId)
        {
            if (Config.Instance.ContainKey<WorldBossConfig>(_bossId))
            {
                return FindPreciousType.WorldBoss;
            }
            else if (Config.Instance.ContainKey<BossHomeConfig>(_bossId))
            {
                return FindPreciousType.BossHome;
            }
            else if (Config.Instance.ContainKey<ElderGodAreaConfig>(_bossId))
            {
                return FindPreciousType.ElderGodArea;
            }
            else if (Config.Instance.ContainKey<DemonJarConfig>(_bossId))
            {
                return FindPreciousType.DemonJar;
            }
            else if (Config.Instance.ContainKey<PersonalBossConfig>(_bossId))
            {
                return FindPreciousType.PersonalBoss;
            }
            return FindPreciousType.None;
        }
        private int GetNextBossNotify()
        {
            if (bossNotifies.Count > 0)
            {
                return bossNotifies[0];
            }
            else
            {
                return 0;
            }
        }
        private void OnBossRebornUpComing(int _bossId)
        {
            AddOneBossRebornNotify(_bossId);
        }
        private void InitializeBossNotify()
        {
            m_CurrentBossNotify = 0;
            bossNotifies.Clear();
            foreach (var boss in bossInfos.Values)
            {
                var bossId = boss.bossId;
                if (Config.Instance.ContainKey<DemonJarConfig>(bossId))
                {
                    if (IsBossAlive(bossId))
                    {
                        var config = Config.Instance.Get<DemonJarConfig>(bossId);
                        var grade = dungeonModel.GetDungeonGrade(new Dungeon(DemonJarModel.DEMONJAR_MAPID, config.LineID));
                        if ((config.CanEnterTimes == 0 || grade == 0))
                        {
                            AddOneBossRebornNotify(bossId);
                        }
                    }
                    else
                    {
                        RemoveOneBossRebornNotify(bossId);
                    }
                }
                else
                {
                    if (IsBossAlive(bossId) || (bossInfos[bossId].refreshTime - DateTime.Now).TotalSeconds < PREPOSE_SECONDS)
                    {
                        AddOneBossRebornNotify(bossId);
                    }
                    else
                    {
                        FindPreciousTimer.Instance.AddClock(bossId, bossInfos[bossId].refreshTime);
                    }
                }
            }
        }
        public class BossInfo
        {
            public int bossId { get; private set; }
            bool isCommunalAlive { get; set; }
            public List<BossKillRecord> killRecords = new List<BossKillRecord>();
            public DateTime refreshTime { get; private set; }
            public List<byte> deadLines = new List<byte>();
            public BossInfo(int _id)
            {
                bossId = _id;
            }
            public void UpdateBossInfo(HA902_tagGCGameWorldBossInfo.tagBossInfoObj _bossInfo)
            {
                isCommunalAlive = _bossInfo.IsAlive == 1;
                killRecords.Clear();
                if (!string.IsNullOrEmpty(_bossInfo.KillRecord))
                {
                    var recordStrings = _bossInfo.KillRecord.Split('|');
                    for (int i = 0; i < recordStrings.Length; i++)
                    {
                        killRecords.Add(new BossKillRecord(recordStrings[i]));
                    }
                }
                refreshTime = DateTime.Now + new TimeSpan(_bossInfo.RefreshSecond * TimeSpan.TicksPerSecond);
            }
            public bool IsBossAlive()
            {
                if (BossFakeLineUtility.Instance.IsShuntBoss(bossId))
                {
                    if (BossFakeLineUtility.Instance.IsBossVisible(bossId))
                    {
                        return true;
                    }
                    else if (BossFakeLineUtility.Instance.IsBossTombstoneVisble(bossId))
                    {
                        return false;
                    }
                    else if ((BossFakeLineUtility.Instance.lastBossNpcID == bossId && Time.realtimeSinceStartup < BossFakeLineUtility.Instance.inMistakeForBossAliveOverTime)
                        && !IsLineBossDead(PlayerDatas.Instance.baseData.FBID))
                    {
                        return true;
                    }
                    else
                    {
                        return isCommunalAlive;
                    }
                }
                else
                {
                    return isCommunalAlive;
                }
            }
            bool IsLineBossDead(int _lineId)
            {
                return deadLines.Contains((byte)_lineId);
            }
        }
        public struct BossSubscribe
        {
            public int bossId;
            public int subscribeState;//0-默认未关注, 1-主动关注, 2-自动关注, 9-主动取消关注
            public bool isAutoSubscribe { get { return this.subscribeState == 2; } }
            public BossSubscribe(int _bossId, int _subscribeState)
            {
                this.bossId = _bossId;
                this.subscribeState = _subscribeState;
            }
        }
        public struct BossKillRecord
        {
            public string playerName;
            public DateTime killTime;
            public long hurt;
            public BossKillRecord(string _record)
            {
                var recordStrings = _record.Split('_');
                killTime = TimeUtility.GetTime(uint.Parse(recordStrings[0]));
                playerName = recordStrings[1];
                hurt = recordStrings.Length > 2 ? long.Parse(recordStrings[2]) : 0;
            }
            public override string ToString()
            {
                return Language.Get("FightTreasure_KillTime", killTime.ToString("HH:mm:ss"), playerName);
            }
        }
        public struct DropRecord
        {
            public int index;
            public DateTime time;
            public string playerName;
            public int mapId;
            public int bossId;
            public int itemId;
            public string userdata;
            public int playerId;
            public int rarility;
            public DropRecord(HA003_tagUniversalGameRecInfo.tagUniversalGameRec _serverInfo)
            {
                this.index = 0;
                this.time = TimeUtility.GetTime(_serverInfo.Time);
                this.playerName = _serverInfo.StrValue1;
                this.mapId = (int)_serverInfo.Value1;
                this.bossId = (int)_serverInfo.Value2;
                this.itemId = (int)_serverInfo.Value3;
                this.userdata = _serverInfo.StrValue3;
                this.playerId = (int)_serverInfo.Value4;
                this.rarility = (int)_serverInfo.Value5;
            }
            public override string ToString()
            {
                var timeString = time.ToString("yyyy-MM-dd HH:mm:ss");
                return Language.Get("FightTreasure_DropRecord", timeString, playerName, playerId, mapId, bossId, itemId, userdata);
            }
            public static int Compare(DropRecord _lhs, DropRecord _rhs)
            {
                var timeStandard = new DateTime(TimeUtility.ServerNow.Year, TimeUtility.ServerNow.Month, TimeUtility.ServerNow.Day, 5, 0, 0);
                if (_lhs.time > timeStandard && _rhs.time < timeStandard)
                {
                    return -1;
                }
                else if (_lhs.time < timeStandard && _rhs.time > timeStandard)
                {
                    return 1;
                }
                else
                {
                    if (_lhs.rarility > _rhs.rarility)
                    {
                        return -1;
                    }
                    else if (_lhs.rarility < _rhs.rarility)
                    {
                        return 1;
                    }
                    else
                    {
                        return _lhs.time > _rhs.time ? -1 : 1;
                    }
                }
            }
            public static int Compare2(DropRecord _lhs, DropRecord _rhs)
            {
                return _lhs.time > _rhs.time ? -1 : 1;
            }
        }
        public enum FindPreciousType
        {
            None,
            WorldBoss,
            BossHome,
            PersonalBoss,
            ElderGodArea,
            DemonJar,
        }
    }
}