using System.Collections; using System.Collections.Generic; using UnityEngine; using System; using System.Text; namespace Snxxz.UI { [XLua.LuaCallCSharp] public class FindPreciousModel : Model, IBeforePlayerDataInitialize, IAfterPlayerDataInitialize, IPlayerLoginOk, IMapInitOk, ISwitchAccount { public const int PREPOSE_SECONDS = 120; public const int FINDPRECIOUS_REDPOINTID = 76000; public const int LOOTPRECIOUs_REDPOINTID = 77000; Redpoint findPreciousRedpoint = new Redpoint(FINDPRECIOUS_REDPOINTID); Redpoint lootPreciousRedpoint = new Redpoint(LOOTPRECIOUs_REDPOINTID); int m_ViewKillRecordsBoss = 0; public int ViewKillRecordsBoss { get { return this.m_ViewKillRecordsBoss; } set { this.m_ViewKillRecordsBoss = value; } } Dictionary bossInfos = new Dictionary(); public List bossNotifies = new List(); BossNotify m_CurrentBossNotify = default(BossNotify); public BossNotify currentBossNotify { get { return m_CurrentBossNotify; } private set { if (m_CurrentBossNotify != value) { m_CurrentBossNotify = value; if (bossRebornNotifyChangeEvent != null) { bossRebornNotifyChangeEvent(); } } } } public List bossDropRecords = new List(); Dictionary bossSubscribes = new Dictionary(); bool serverInited = false; public event Action bossInfoUpdateEvent; public event Action bossSubscribeChangeEvent; public event Action preciousDropRecordUpdateEvent; public event Action bossRebornNotifyChangeEvent; DungeonModel dungeonModel { get { return ModelCenter.Instance.GetModel(); } } DemonJarModel demonJarModel { get { return ModelCenter.Instance.GetModel(); } } WorldBossModel worldBossModel { get { return ModelCenter.Instance.GetModel(); } } BossHomeModel bossHomeModel { get { return ModelCenter.Instance.GetModel(); } } PersonalBossModel personalBossModel { get { return ModelCenter.Instance.GetModel(); } } JadeDynastyBossModel jadeDynastyBossModel { get { return ModelCenter.Instance.GetModel(); } } RealmModel realmModel { get { return ModelCenter.Instance.GetModel(); } } 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; RequestQueryBossInfo(0); InitializeBossNotify(); } public void OnSwitchAccount() { m_CurrentBossNotify = default(BossNotify); bossSubscribes.Clear(); bossNotifies.Clear(); FindPreciousTimer.Instance.Clear(); } public void OnMapInitOk() { var mapId = PlayerDatas.Instance.baseData.MapID; var mapConfig = MapConfig.Get(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 RequestQueryBossInfo(int bossId) { var sendInfo = new CA904_tagCGQueryBossInfo(); if (bossId == 0) { sendInfo.Count = 0; sendInfo.BossIDList = new uint[] { }; } else { sendInfo.Count = 1; sendInfo.BossIDList = new uint[] { (uint)bossId }; } GameNetSystem.Instance.SendInfo(sendInfo); } public void OnPreciousDropRecordUpdate(HA003_tagUniversalGameRecInfo _serverInfo) { if (_serverInfo.Type != 25) { return; } bossDropRecords.Clear(); foreach (var item in _serverInfo.UniversalGameRec) { bossDropRecords.Add(new DropRecord(item)); } bossDropRecords.Sort(DropRecord.Compare); if (bossDropRecords.Count > 5) { var records2 = new List(); for (int i = bossDropRecords.Count - 1; i >= 5; i--) { records2.Add(bossDropRecords[i]); bossDropRecords.RemoveAt(i); } records2.Sort(DropRecord.Compare2); 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 (!bossNewAliveState) { RemoveOneBossRebornNotify(bossId); } if (bossNewAliveState != bossOldAliveState) { if (DemonJarConfig.Has(bossId)) { if (bossNewAliveState) { var config = DemonJarConfig.Get(bossId); var grade = dungeonModel.GetGrade(new Dungeon(DemonJarModel.DATA_MAPID, config.LineID)); if ((config.CanEnterTimes == 0 || grade == 0)) { AddOneBossRebornNotify(bossId); } } } else { if (bossNewAliveState || (bossInfos[bossId].refreshTime - TimeUtility.ServerNow).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.lineToAlives.Clear(); for (var j = 0; j < bossLineInfo.LineIDList.Length; j++) { var line = bossLineInfo.LineIDList[j]; var state = bossLineInfo.StateList[j]; bossInfo.lineToAlives[line] = state == 1; } } } } public bool TryGetBossInfo(int _bossId, out BossInfo _bossInfo) { return bossInfos.TryGetValue(_bossId, out _bossInfo); } public bool IsBossUnlock(int bossId) { var myRealmLevel = PlayerDatas.Instance.baseData.realmLevel; var config = NPCConfig.Get(bossId); return myRealmLevel >= config.Realm; } public bool IsSameBigRealmStageBoss(int bossId) { var myRealmLevel = PlayerDatas.Instance.baseData.realmLevel; var myRealmStage = realmModel.GetRealmStage(myRealmLevel); var config = NPCConfig.Get(bossId); var bossRealmStage = realmModel.GetRealmStage(config.Realm); return myRealmStage == bossRealmStage; } public int GetBossUnLockRealm(int bossId) { var config = NPCConfig.Get(bossId); return config.Realm; } public bool IsBossAlive(int _bossId) { if (demonJarModel.IsPersonalBoss(_bossId)) { return true; } else { return bossInfos.ContainsKey(_bossId) && bossInfos[_bossId].IsBossAlive(); } } public List GetBossKillRecords(int _bossId) { if (bossInfos.ContainsKey(_bossId)) { return bossInfos[_bossId].killRecords; } else { return null; } } public List GetBossSubscribes() { return new List(bossSubscribes.Keys); } 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(); } if (bossSubscribeChangeEvent != null) { bossSubscribeChangeEvent(_bossId); } } public void RequestDeSubscribeBoss(int _bossId) { var sendInfo = new CA903_tagCGAttentionBoss(); sendInfo.BossID = (uint)_bossId; sendInfo.IsAdd = 9; 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) && !ExitBossNotify(bossId)) { var notify = new BossNotify(bossId, demonJarModel.autoChallenge); var type = GetBossFindPreciousType(bossId); if (type == FindPreciousType.DemonJar) { if (demonJarModel.GetSurplusTimes() > 0) { if (!AutoGotoSkillDemonJarBoss(notify)) { bossNotifies.Add(notify); currentBossNotify = GetNextBossNotify(); } } } else { bossNotifies.Add(notify); currentBossNotify = GetNextBossNotify(); } } } public void RemoveOneBossRebornNotify(int bossId) { if (ExitBossNotify(bossId)) { RemoveBossRebornNotify(bossId); currentBossNotify = GetNextBossNotify(); } } public void ReportConfirmBossRebornNotify(BossNotify _notify) { if (bossNotifies.Contains(_notify)) { bossNotifies.Remove(_notify); } currentBossNotify = GetNextBossNotify(); } public void RemoveRebornNotifies(FindPreciousType _type) { for (int i = bossNotifies.Count - 1; i >= 0; i--) { var notify = bossNotifies[i]; if (GetBossFindPreciousType(notify.bossId) == _type) { bossNotifies.Remove(notify); } } currentBossNotify = GetNextBossNotify(); } private void UpdateRedpoint(int _redpointId) { if (_redpointId == WorldBossModel.WORLDBOSS_REDPOINT || _redpointId == PersonalBossModel.PERSONAL_REDPOINTID || _redpointId == DemonJarModel.DEMONJAR_REDPOINTID ) { var worldBossRedpointCount = worldBossModel.worldBossRedPoint.count; var personalBossRedpointCount = personalBossModel.personalRedpoint.count; var demonJarRedpointCount = demonJarModel.redpoint.count; var totalCount = worldBossRedpointCount + personalBossRedpointCount + demonJarRedpointCount; findPreciousRedpoint.state = totalCount > 0 ? RedPointState.Quantity : RedPointState.None; findPreciousRedpoint.count = totalCount; } if (_redpointId == JadeDynastyBossModel.JADEDYNASTY_REDPOINTID) { var jadeDynastyBossRedpointCount = jadeDynastyBossModel.redpoint.count; var totalCount = jadeDynastyBossRedpointCount; lootPreciousRedpoint.count = totalCount; lootPreciousRedpoint.state = totalCount > 0 ? RedPointState.Quantity : RedPointState.None; } } public FindPreciousType GetBossFindPreciousType(int _bossId) { if (WorldBossConfig.Has(_bossId)) { return FindPreciousType.WorldBoss; } else if (BossHomeConfig.Has(_bossId)) { return FindPreciousType.BossHome; } else if (ElderGodAreaConfig.Has(_bossId)) { return FindPreciousType.ElderGodArea; } else if (DemonJarConfig.Has(_bossId)) { return FindPreciousType.DemonJar; } else if (PersonalBossConfig.Has(_bossId)) { return FindPreciousType.PersonalBoss; } else if (CrossServerBossConfig.Has(_bossId)) { return FindPreciousType.CrossServerBoss; } else if (jadeDynastyBossModel.IsJadeDynastyBoss(_bossId)) { return FindPreciousType.JadeDynastyBoss; } return FindPreciousType.None; } public BossNotify GetNextBossNotify() { if (bossNotifies.Count > 0) { return bossNotifies[0]; } else { return default(BossNotify); } } private bool ExitBossNotify(int bossId) { foreach (var notify in bossNotifies) { return notify.bossId == bossId; } return false; } private void RemoveBossRebornNotify(int bossId) { for (var i = bossNotifies.Count - 1; i >= 0; i--) { var notify = bossNotifies[i]; if (notify.bossId == bossId) { bossNotifies.RemoveAt(i); } } } private void OnBossRebornUpComing(int _bossId) { AddOneBossRebornNotify(_bossId); } private void InitializeBossNotify() { m_CurrentBossNotify = default(BossNotify); bossNotifies.Clear(); foreach (var boss in bossInfos.Values) { var bossId = boss.bossId; if (DemonJarConfig.Has(bossId)) { if (FuncOpen.Instance.IsFuncOpen(76) && IsBossAlive(bossId)) { var config = DemonJarConfig.Get(bossId); var grade = dungeonModel.GetGrade(new Dungeon(DemonJarModel.DATA_MAPID, config.LineID)); if ((config.CanEnterTimes == 0 || grade == 0)) { AddOneBossRebornNotify(bossId); } } else { RemoveOneBossRebornNotify(bossId); } } else { if (IsBossAlive(bossId) || (bossInfos[bossId].refreshTime - TimeUtility.ServerNow).TotalSeconds < PREPOSE_SECONDS) { AddOneBossRebornNotify(bossId); } else { FindPreciousTimer.Instance.AddClock(bossId, bossInfos[bossId].refreshTime); } } } } public bool AutoGotoSkillDemonJarBoss(BossNotify notify) { if (CrossServerUtility.IsCrossServer()) { return false; } if (!demonJarModel.autoChallenge) { return false; } if (!notify.demonJarAuto) { return false; } if (DTCB105_tagMCPlayerWallow.forceOffLine) { return false; } if (NewBieCenter.Instance.inGuiding) { return false; } if (!TaskModel.IsOPenAutoResolve()) { return false; } if (PlayerDatas.Instance.hero != null && PlayerDatas.Instance.hero.CurMapArea == (int)MapArea.E_Type.Boss) { return false; } if (PlayerDatas.Instance.hero != null && Time.realtimeSinceStartup - PlayerDatas.Instance.hero.calculAutoFightTime < GeneralDefine.demonJarAutoTime) { return false; } if (PlayerDatas.Instance.hero != null && PlayerDatas.Instance.hero.ActorInfo.serverDie) { return false; } if (PlayerDatas.Instance.hero != null && PlayerDatas.Instance.hero.IsDaZuo()) { return false; } if (PlayerDatas.Instance.extersion.bossState == 1) { return false; } if (PlayerDatas.Instance.extersion.pkState == 1) { return false; } if (MapTransferUtility.Instance.NpcID != 0) { return false; } var surplusTimes = demonJarModel.GetSurplusTimes(); var needTimes = demonJarModel.isDoubleAward ? 2 : 1; if (surplusTimes < needTimes) { return false; } var mapId = PlayerDatas.Instance.baseData.MapID; var mapConfig = MapConfig.Get(mapId); if (GeneralDefine.neutralMaps.Contains(mapId)) { return false; } if (mapConfig.MapFBType != (int)MapType.OpenCountry) { return false; } if ((TimeUtility.ServerNow - TaskAllocation.Instance.TaskTime).TotalSeconds < 30) { return false; } if (WindowCenter.Instance.ExistAnyFullScreenOrMaskWin()) { return false; } if (WindowCenter.Instance.IsOpen("DemonJarWin") || WindowCenter.Instance.IsOpen("DemonJarAutoDoubleSettingWin")) { return false; } var bossId = notify.bossId; var config = DemonJarConfig.Get(bossId); dungeonModel.SingleChallenge(DemonJarModel.DATA_MAPID, config.LineID); demonJarModel.autoChallengeBoss = bossId; return true; } public class BossInfo { public int bossId { get; private set; } bool isCommunalAlive { get; set; } public List killRecords = new List(); public DateTime refreshTime { get; private set; } public Dictionary lineToAlives = new Dictionary(); public int rebornTotalCd { get; private set; } public BossInfo(int _id) { bossId = _id; } public void UpdateBossInfo(HA902_tagGCGameWorldBossInfo.tagBossInfoObj _bossInfo) { isCommunalAlive = _bossInfo.IsAlive == 1; rebornTotalCd = (int)_bossInfo.RefreshCD; 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 = TimeUtility.ServerNow + 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.HasSawLineBossRecently(bossId, PlayerDatas.Instance.baseData.FBID)) { return true; } else if (BossFakeLineUtility.Instance.HasSawLineStoneRecently(bossId, PlayerDatas.Instance.baseData.FBID)) { return false; } else { var currentNeutralMap = false; if (WorldBossConfig.Has(bossId)) { var worldBossConfig = WorldBossConfig.Get(bossId); currentNeutralMap = worldBossConfig.MapID == PlayerDatas.Instance.baseData.MapID; currentNeutralMap = currentNeutralMap && GeneralDefine.neutralMaps.Contains(worldBossConfig.MapID); } if (currentNeutralMap) { return IsLineBossAlive(PlayerDatas.Instance.baseData.FBID); } else { if (BossFakeLineUtility.Instance.IsBossKilledRecently(bossId)) { return !IsAnyLineBossDead(); } else { return IsAnyLineBossAlive(); } } } } else { return isCommunalAlive; } } bool IsLineBossAlive(int _lineId) { return lineToAlives.ContainsKey(_lineId) && lineToAlives[_lineId]; } bool IsAnyLineBossAlive() { foreach (var item in lineToAlives) { if (item.Value) { return true; } } return false; } bool IsAnyLineBossDead() { foreach (var item in lineToAlives) { if (!item.Value) { return true; } } return false; } } 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 lineId; public int bossId; public int itemId; public string userdata; public int playerId; public int rarility; public int serverGroupId; public int playerLevel; public DropRecord(HA003_tagUniversalGameRecInfo.tagUniversalGameRec _serverInfo) { this.index = 0; this.time = TimeUtility.GetTime(_serverInfo.Time); this.playerName = _serverInfo.StrValue1; this.mapId = (int)_serverInfo.Value1 / 100; this.lineId = (int)_serverInfo.Value1 % 100; this.bossId = (int)_serverInfo.Value2; this.itemId = (int)_serverInfo.Value3; this.userdata = _serverInfo.StrValue3; this.playerId = (int)_serverInfo.Value4; this.rarility = (int)_serverInfo.Value5; this.serverGroupId = 0; this.playerLevel = 0; var strValue2Array = _serverInfo.StrValue2.Split('|'); if (strValue2Array.Length > 1) { this.serverGroupId = int.Parse(strValue2Array[0]); this.playerLevel = int.Parse(strValue2Array[1]); } } 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, serverGroupId, playerLevel, lineId); } 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 struct BossNotify { public int bossId; public bool demonJarAuto; public BossNotify(int bossId, bool demonJarAuto) { this.bossId = bossId; this.demonJarAuto = demonJarAuto; } public static bool operator ==(BossNotify _lhs, BossNotify _rhs) { return _lhs.bossId == _rhs.bossId && _lhs.demonJarAuto == _rhs.demonJarAuto; } public static bool operator !=(BossNotify _lhs, BossNotify _rhs) { return _lhs.bossId != _rhs.bossId || _lhs.demonJarAuto != _rhs.demonJarAuto; } } } }