using System; using System.Collections.Generic; using System.Linq; using System.Text; using LitJson; using UnityEngine; namespace vnxbqy.UI { public class CrossServerOneVsOneModel : Model, IBeforePlayerDataInitialize, IAfterPlayerDataInitialize, ISwitchAccount, IPlayerLoginOk { public string PkResultLocalSaveKey { get; private set; } public List localSaveResults { get; private set; } CrossServerOneVsOneRewardModel rewardModel { get { return ModelCenter.Instance.GetModel(); } } public event Action UpdateDayAwardsEvent; public const int CrossServerDataMapId = 32010; DungeonModel dungeonModel { get { return ModelCenter.Instance.GetModel(); } } public bool isClickCoolTime { get; set; } public event Action UpdateMatchStateEvent; private bool _isMatching; public bool IsMatching { get { return _isMatching; } set { _isMatching = value; if (UpdateMatchStateEvent != null) { UpdateMatchStateEvent(); } } } public DateTime matchStartTime { get; set; } public DateTime roundEndTime { get; private set; } StoreModel storeModel { get { return ModelCenter.Instance.GetModel(); } } public string LocalSaveThirdTypeKey = string.Empty; private int recordDataMapId; private int loadSecond; public override void Init() { IsMatching = false; ParseFuncConfig(); SetHonorRedpoint(); } public void OnBeforePlayerDataInitialize() { loadSecond = 0; StageLoad.Instance.onStageLoadFinish -= OnLoadMapFinish; storeModel.RefreshBuyShopLimitEvent -= UpdateBuyShop; TimeUtility.OnServerOpenDayRefresh -= UpdateServerOpenDay; PlayerDatas.Instance.playerDataRefreshEvent -= UpdatePlayerData; CrossServerOneVsOnePlayerInfo.Instance.UpdatePlayerInfoEvent -= UpdatePlayerInfo; CrossServerOneVsOnePKSeason.Instance.updateSelfSeasonEvent -= UpdateSeason; TimeMgr.Instance.OnMinuteEvent -= UpdateMinute; GlobalTimeEvent.Instance.secondEvent -= UpdateSecond; dungeonModel.updateMissionEvent -= UpdateFBHelp; rewardModel.CrossRealmPKAwardStateUpdate -= UpdateDayAwardState; CrossServerOneVsOnePlayerInfo.Instance.UpdatePlayerInfoEvent -= UpdateDayAwardState; InitData(); } public void OnAfterPlayerDataInitialize() { int playerId = (int)PlayerDatas.Instance.baseData.PlayerID; PkResultLocalSaveKey = StringUtility.Contact("PkResultLocalSaveKey", playerId); LocalSaveThirdTypeKey = StringUtility.Contact("HonorStoreThirdType", playerId); GetLocalSaveData(); } public void OnSwitchAccount() { IsMatching = false; } public void OnPlayerLoginOk() { StageLoad.Instance.onStageLoadFinish += OnLoadMapFinish; storeModel.RefreshBuyShopLimitEvent += UpdateBuyShop; TimeUtility.OnServerOpenDayRefresh += UpdateServerOpenDay; PlayerDatas.Instance.playerDataRefreshEvent += UpdatePlayerData; CrossServerOneVsOnePlayerInfo.Instance.UpdatePlayerInfoEvent += UpdatePlayerInfo; CrossServerOneVsOnePKSeason.Instance.updateSelfSeasonEvent += UpdateSeason; TimeMgr.Instance.OnMinuteEvent += UpdateMinute; GlobalTimeEvent.Instance.secondEvent += UpdateSecond; rewardModel.CrossRealmPKAwardStateUpdate += UpdateDayAwardState; CrossServerOneVsOnePlayerInfo.Instance.UpdatePlayerInfoEvent += UpdateDayAwardState; dungeonModel.updateMissionEvent += UpdateFBHelp; UpdateServerOpenDay(); UpdateDayAwardState(); if (IsMatching && CrossServerOneVsOnePKSeason.Instance.InOpenTime()) { SendCrossMatch(1); } UpdateCrossDayAwardsRedpoint(); UpdateCrossMatchRedpoint(); UpdateCanBuyRedpoint(); } public override void UnInit() { } private void InitData() { CrossServerOneVsOnePKSeason.Instance.InitData(); CrossServerOneVsOnePlayerInfo.Instance.InitData(); pkResultInfo = new CrossServerOneVsOnePkResult(); oneVsOneHistoryDict.Clear(); } private void UpdateSecond() { loadSecond += 1; if (loadSecond >= 5) { recordDataMapId = dungeonModel.GetDataMapIdByMapId(PlayerDatas.Instance.baseData.MapID); GlobalTimeEvent.Instance.secondEvent -= UpdateSecond; loadSecond = 0; DebugEx.Log("UpdateSecond....." + recordDataMapId); } } private void OnLoadMapFinish() { var dataMapId = dungeonModel.GetDataMapIdByMapId(PlayerDatas.Instance.baseData.MapID); if ((recordDataMapId == CrossServerDataMapId || recordDataMapId == 1000) && dataMapId != CrossServerDataMapId) { var pkSeason = CrossServerOneVsOnePKSeason.Instance; if (pkSeason.IsEnterCrossServer()) { WindowCenter.Instance.Open(false, 0); } } recordDataMapId = dataMapId; } private void UpdateMinute() { UpdateCrossMatchRedpoint(); if (!IsMatching) return; if (!CrossServerOneVsOnePKSeason.Instance.isSatisfyMatch) { IsMatching = false; SendCrossMatch(0); } } public void UpdateDayAwardState() { var playerInfo = CrossServerOneVsOnePlayerInfo.Instance; for (int i = 0; i < dayAwardTypelist.Count; i++) { var dayAward = dayAwardTypelist[i]; int awardType = dayAward.type; switch (awardType) { case 1: dayAward.IsReceived = rewardModel.IsAwardState(CrossRealmPKAwardStateEnum.DayWinCountAwardState, dayAward.index); dayAward.SetCompletedNum(playerInfo.DayWinCount); break; case 2: dayAward.IsReceived = rewardModel.IsAwardState(CrossRealmPKAwardStateEnum.DayPKCountAwardState, dayAward.index); dayAward.SetCompletedNum(playerInfo.DayPKCount); break; } } if (UpdateDayAwardsEvent != null) { UpdateDayAwardsEvent(); } UpdateCrossDayAwardsRedpoint(); } private void UpdateSeason() { UpdateCrossMatchRedpoint(); UpdateCanBuyRedpoint(); } private void UpdateBuyShop() { var pkSeason = CrossServerOneVsOnePKSeason.Instance; if (!pkSeason.IsEnterCrossServer()) return; UpdateCanBuyRedpoint(); } private void UpdatePlayerInfo() { UpdateCrossDayAwardsRedpoint(); UpdateCrossMatchRedpoint(); } private void UpdateFBHelp() { if (!CrossServerUtility.IsCrossServerOneVsOne()) { return; } var hero = PlayerDatas.Instance.hero; var mission = dungeonModel.mission; if (mission.prepareTime > 0) { roundEndTime = DateTime.Now + new TimeSpan(mission.prepareTime * TimeSpan.TicksPerMillisecond); if (!WindowCenter.Instance.IsOpen()) { WindowCenter.Instance.Open(); } if (hero != null) { hero.Behaviour.StopHandupAI(true); hero.StopPathFind(); } } DebugEx.LogFormat("副本帮助信息回合是否开始::{0}", mission.isStart); if (mission.isStart == 1) { if (WindowCenter.Instance.IsOpen()) { WindowCenter.Instance.Close(); } if (!WindowCenter.Instance.IsOpen()) { WindowCenter.Instance.Open(); } if (hero != null) { hero.Behaviour.StartHandupAI(); } } } public List GetDayAwardsList() { dayAwardTypelist.Sort(CompareByCompleteProgress); return dayAwardTypelist; } public int CompareByCompleteProgress(AwardType start, AwardType end) { int x = (int)start.progress; int y = (int)end.progress; if (x.CompareTo(y) != 0) return x.CompareTo(y); x = start.type; y = end.type; if (x.CompareTo(y) != 0) return x.CompareTo(y); x = start.num; y = end.num; if (x.CompareTo(y) != 0) return x.CompareTo(y); return 0; } public bool IsNewDay { get; private set; } private void UpdateServerOpenDay() { var pkSeason = CrossServerOneVsOnePKSeason.Instance; if (!pkSeason.IsEnterCrossServer()) return; IsNewDay = false; int openDay = TimeUtility.OpenDay; if (!PlayerPrefs.HasKey(LocalSaveThirdTypeKey)) { IsNewDay = true; LocalSave.SetInt(LocalSaveThirdTypeKey, openDay); } else { int localOpenDay = LocalSave.GetInt(LocalSaveThirdTypeKey); if (openDay != localOpenDay) { IsNewDay = true; LocalSave.SetInt(LocalSaveThirdTypeKey, openDay); } } UpdateCanBuyRedpoint(); } #region 表数据 public int freeMaxMatchNum { get; private set; } //每日免费匹配次数 public int buyMaxMatchNum { get; private set; } //每日可购买次数 public string priceFormula { get; private set; } //购买匹配次数需要价格公式 public string winStreakScoreFormula { get; private set; } //连胜积分公式 public List dayAwardTypelist { get; private set; } public int afterOpenDayOpenCross { get; private set; } private void ParseFuncConfig() { var CrossRealmPKAward = FuncConfigConfig.Get("CrossRealmPKAward"); var dayMatchAwardData = JsonMapper.ToObject(CrossRealmPKAward.Numerical1); var dayWinAwardData = JsonMapper.ToObject(CrossRealmPKAward.Numerical2); dayAwardTypelist = new List(); int dayWinIndex = 0; foreach (var num in dayWinAwardData.Keys) { int times = int.Parse(num); var items = dayWinAwardData[num]; var awardType = new AwardType(times, 1, dayWinIndex); dayAwardTypelist.Add(awardType); if (items.IsArray) { for (int i = 0; i < items.Count; i++) { var itemInfo = items[i]; if (itemInfo.IsArray && itemInfo.Count >= 3) { int id = 0; int.TryParse(itemInfo[0].ToString(), out id); int count = 0; int.TryParse(itemInfo[1].ToString(), out count); int isBind = 0; int.TryParse(itemInfo[2].ToString(), out isBind); AwardItem awardItem = new AwardItem(id, count, isBind); awardType.SetAwardItems(awardItem); } } } dayWinIndex += 1; } int dayPkIndex = 0; foreach (var num in dayMatchAwardData.Keys) { int times = int.Parse(num); var items = dayMatchAwardData[num]; var awardType = new AwardType(times, 2, dayPkIndex); dayAwardTypelist.Add(awardType); if (items.IsArray) { for (int i = 0; i < items.Count; i++) { var itemInfo = items[i]; if (itemInfo.IsArray && itemInfo.Count >= 3) { int id = 0; int.TryParse(itemInfo[0].ToString(), out id); int count = 0; int.TryParse(itemInfo[1].ToString(), out count); int isBind = 0; int.TryParse(itemInfo[2].ToString(), out isBind); AwardItem awardItem = new AwardItem(id, count, isBind); awardType.SetAwardItems(awardItem); } } } dayPkIndex += 1; } var CrossRealmPKMatchCount = FuncConfigConfig.Get("CrossRealmPKMatchCount"); freeMaxMatchNum = int.Parse(CrossRealmPKMatchCount.Numerical1); buyMaxMatchNum = int.Parse(CrossRealmPKMatchCount.Numerical2); priceFormula = CrossRealmPKMatchCount.Numerical3; var CrossRealmPKScore = FuncConfigConfig.Get("CrossRealmPKScore"); winStreakScoreFormula = CrossRealmPKScore.Numerical3; var CrossRealmCfg = FuncConfigConfig.Get("CrossRealmCfg"); afterOpenDayOpenCross = int.Parse(CrossRealmCfg.Numerical1); } public class AwardType { public int type { get; private set; } //1 胜利奖励 2 匹配奖励 public int index { get; private set; } public int num { get; private set; } public int curCompletedNum { get; private set; } public CompleteProgress progress { get; private set; } public bool IsReceived { get; set; } public List awardItems = new List(); public AwardType(int _num, int _type, int _index) { type = _type; num = _num; index = _index; curCompletedNum = 0; IsReceived = false; progress = CompleteProgress.Completed; awardItems.Clear(); } public void SetAwardItems(AwardItem awardItem) { awardItems.Add(awardItem); } public void SetCompletedNum(int completedNum) { curCompletedNum = completedNum; if (IsReceived) { curCompletedNum = num; progress = CompleteProgress.AlreadyReceived; } else { progress = curCompletedNum < num ? CompleteProgress.UnCompleted : CompleteProgress.Completed; } } public enum CompleteProgress { Completed = 0, //已达成 UnCompleted = 1, //未达成 AlreadyReceived = 2, //已领取 } } public struct AwardItem { public int itemId; public int itemCount; public int isBind; public AwardItem(int _id, int _count, int _isBind) { itemId = _id; itemCount = _count; isBind = _isBind; } } #endregion #region 协议 public CrossServerOneVsOnePkResult pkResultInfo { get; private set; } public event Action UpdatePkResultEvent; public void UpdatePKResultInfo(HC003_tagGCCrossRealmPKOverInfo pKOverInfo) { pkResultInfo = new CrossServerOneVsOnePkResult(); pkResultInfo.UpdatePkResult(pKOverInfo); SetPkInfoLocalSave(pkResultInfo); if (UpdatePkResultEvent != null) { UpdatePkResultEvent(); } } BuffModel buffDatas { get { return ModelCenter.Instance.GetModel(); } } /// ///0-取消匹配; 1-进行匹配 /// /// public void SendCrossMatch(int type) { if (type == 1 && TryGetMatchTip()) return; var match = new CC101_tagCMCrossRealmPKMatch(); match.Type = (byte)type; GameNetSystem.Instance.SendInfo(match); CrossServerOneVsOneRewardModel.PkType = buffDatas.PkType; } public void SendBuyMatchCount() { var pKBuy = new CC102_tagCMCrossRealmPKBuy(); GameNetSystem.Instance.SendInfo(pKBuy); } public bool TryGetMatchTip() { int mapId = PlayerDatas.Instance.baseData.MapID; bool isCrossDungeon = CrossServerUtility.IsCrossServer(); if (isCrossDungeon) { SysNotifyMgr.Instance.ShowTip("CrossMatching3"); return true; } var mapConfig = MapConfig.Get(mapId); bool isDungeon = mapConfig != null && mapConfig.MapFBType != 0 ? true : false; if (isDungeon) { SysNotifyMgr.Instance.ShowTip("CrossMatching4"); return true; } var deadModel = ModelCenter.Instance.GetModel(); if (deadModel.playerIsDie) { SysNotifyMgr.Instance.ShowTip("CrossMatching5"); return true; } var teamModel = ModelCenter.Instance.GetModel(); bool isTeamMatch = teamModel.isMatching; if (isTeamMatch) { SysNotifyMgr.Instance.ShowTip("CrossMatching6"); return true; } bool isDungeonPrepare = teamModel.teamPrepare.isPreparing; if (isDungeonPrepare) { SysNotifyMgr.Instance.ShowTip("CrossMatching7"); return true; } int remainMatchNum = CrossServerOneVsOnePlayerInfo.Instance.GetDayRemainNum(); if (remainMatchNum <= 0) { SysNotifyMgr.Instance.ShowTip("CrossMatching16"); return true; } return false; } public bool TryGetBuyMatchTimes(string key) { if (!CrossServerOneVsOnePKSeason.Instance.isSatisfyMatch) { SysNotifyMgr.Instance.ShowTip(key); return false; } int remainNum = CrossServerOneVsOnePlayerInfo.Instance.GetDayRemainNum(); if (remainNum >= freeMaxMatchNum) { SysNotifyMgr.Instance.ShowTip("CrossMatching13"); return false; } return true; } #endregion #region 历史记录 Dictionary oneVsOneHistoryDict = new Dictionary(); public event Action oneVsOneHistoryRefresh; public void OnReceivePackage(HC103_tagMCCrossRealmPKPlayerHisSeasonInfo package) { oneVsOneHistoryDict.Clear(); for (int i = 0; i < package.Count; i++) { var data = package.SeasonList[i]; oneVsOneHistoryDict[data.SeasonID] = new CrossServerOneVsOneHistory() { season = data.SeasonID, division = data.DanLV, order = data.Order, rewardLevel = data.AwardLV, score = (int)data.Score }; } if (oneVsOneHistoryRefresh != null) { oneVsOneHistoryRefresh(); } } public bool TryGetOneVsOneHistory(int session, out CrossServerOneVsOneHistory history) { return oneVsOneHistoryDict.TryGetValue(session, out history); } public struct CrossServerOneVsOneHistory { public int season; public int order; public int division; public int rewardLevel; public int score; } #endregion #region 匹配记录 private void GetLocalSaveData() { localSaveResults = new List(); string[] localJsons = LocalSave.GeStringArray(PkResultLocalSaveKey); if (localJsons != null) { for (int i = 0; i < localJsons.Length; i++) { CrossServerOneVsOnePkResult resultInfo = JsonMapper.ToObject(localJsons[i]); localSaveResults.Add(resultInfo); } } } public void SetPkInfoLocalSave(CrossServerOneVsOnePkResult resultInfo) { if (localSaveResults.Count >= 30) { localSaveResults.RemoveAt(localSaveResults.Count - 1); } localSaveResults.Insert(0, resultInfo); string[] localJsons = new string[localSaveResults.Count]; for (int i = 0; i < localJsons.Length; i++) { string json = JsonMapper.ToJson(localSaveResults[i]); localJsons[i] = json; } LocalSave.SetStringArray(PkResultLocalSaveKey, localJsons); } #endregion #region 红点 public const int CrossOneVsOneRedKey = 21301; public Redpoint crossOneVsOneRedpoint = new Redpoint(CrossServerUtility.CrossServerRedKey, CrossOneVsOneRedKey); public const int CrossArenaRedKey = 2130101; public Redpoint crossArenaRedpoint = new Redpoint(CrossOneVsOneRedKey, CrossArenaRedKey); public const int CrossDayAwardsRedKey = 21301011; public Redpoint crossDayAwardsRedpoint = new Redpoint(CrossArenaRedKey, CrossDayAwardsRedKey); public const int CrossMatchRedKey = 21301012; public Redpoint crossMatchRedpoint = new Redpoint(CrossArenaRedKey, CrossMatchRedKey); public void UpdateCrossDayAwardsRedpoint() { bool isReceive = false; for (int i = 0; i < dayAwardTypelist.Count; i++) { var awardType = dayAwardTypelist[i]; if (awardType.progress == AwardType.CompleteProgress.Completed) { isReceive = true; break; } } if (isReceive) { crossDayAwardsRedpoint.state = RedPointState.Simple; } else { crossDayAwardsRedpoint.state = RedPointState.None; } CrossServerUtility.UpdateCrossServerRedpoint(); } public void UpdateCrossMatchRedpoint() { var playerInfo = CrossServerOneVsOnePlayerInfo.Instance; var pkSeason = CrossServerOneVsOnePKSeason.Instance; if (pkSeason.isSatisfyMatch && playerInfo.GetDayRemainNum() > 0) { crossMatchRedpoint.state = RedPointState.Simple; } else { crossMatchRedpoint.state = RedPointState.None; } if (crossMatchRedpoint.state != RedPointState.None) { CrossServerUtility.UpdateCrossServerRedpoint(); } } #region 荣誉商店红点 public const int CrossHonorStoreRedKey = 2130104; public Redpoint crossHonorStoreRedpoint = new Redpoint(CrossOneVsOneRedKey, CrossHonorStoreRedKey); private Dictionary honorRedpointDict = new Dictionary(); public void SetHonorRedpoint() { honorRedpointDict.Clear(); List storelist = StoreConfig.GetValues(); for (int i = 0; i < storelist.Count; i++) { StoreConfig storeConfig = storelist[i]; int redKey = 0; Redpoint redpoint = null; if (storeConfig.ShopType == (int)StoreFunc.CrossOneVsOneHonor) { redKey = CrossHonorStoreRedKey * 100 + storeConfig.ID; redpoint = new Redpoint(CrossHonorStoreRedKey, redKey); honorRedpointDict.Add(storeConfig.ID, redpoint); } } } public Redpoint GetRedpointById(int shopId) { Redpoint redpoint = null; honorRedpointDict.TryGetValue(shopId, out redpoint); return redpoint; } private void UpdatePlayerData(PlayerDataType type) { switch (type) { case PlayerDataType.CDBPlayerRefresh_Honor: UpdateCanBuyRedpoint(); break; } } public void UpdateCanBuyRedpoint() { var pkSeason = CrossServerOneVsOnePKSeason.Instance; if (!pkSeason.IsEnterCrossServer()) return; List storeDatas = storeModel.TryGetStoreDatas(StoreFunc.CrossOneVsOneHonor); if (storeDatas != null) { for (int i = 0; i < storeDatas.Count; i++) { var storeData = storeDatas[i]; var storeConfig = storeData.storeConfig; int type = 0; TryGetRedTypeByShopId(storeConfig.ID, out type); if (type == 6) { string key = StringUtility.Contact(PlayerDatas.Instance.baseData.PlayerID, "ShopId", storeData.shopId); int remainNum = 0; honorRedpointDict[storeConfig.ID].state = RedPointState.None; if (!storeModel.TryGetIsSellOut(storeConfig, out remainNum)) { if (!PlayerPrefs.HasKey(key) || IsNewDay) { if (UIHelper.GetMoneyCnt(storeConfig.MoneyType) >= (ulong)storeConfig.MoneyNumber) { honorRedpointDict[storeConfig.ID].state = RedPointState.Simple; LocalSave.SetBool(key, true); } } else { if (LocalSave.GetBool(key)) { if (UIHelper.GetMoneyCnt(storeConfig.MoneyType) >= (ulong)storeConfig.MoneyNumber) { honorRedpointDict[storeConfig.ID].state = RedPointState.Simple; } } } } } } } CrossServerUtility.UpdateCrossServerRedpoint(); } public bool TryGetRedTypeByShopId(int shopId, out int type) { type = 0; var ruleDict = storeModel.storeRedRuleDict; foreach (var key in ruleDict.Keys) { List idlist = ruleDict[key]; if (idlist.Contains(shopId)) { type = key; return true; } } return false; } public void ClearRedpoint(int shopId) { IsNewDay = false; string record = StringUtility.Contact(PlayerDatas.Instance.baseData.PlayerID, "ShopId", shopId); if (honorRedpointDict[shopId].state != RedPointState.None) { honorRedpointDict[shopId].state = RedPointState.None; LocalSave.SetBool(record, false); } } #endregion #endregion } }