using System; using System.Collections.Generic; using System.Linq; using UnityEngine; using LitJson; using System.Collections; public class BuyShopItemLimit { public uint ItemIndex; public int BuyCnt; // 今日已购买次数 public int isReset; //是否属于每月重置 0 不重置 1重置 } public struct ShopItemInfo { public int itemId; public int count; public ShopItemInfo(int id, int count) { this.itemId = id; this.count = count; } } public class StoreModel : GameSystemManager { public string UNIONSTORESAVE_KEY { get; private set; } public string MUSTBUYSAVE_KEY { get; private set; } public string StoreEffectRecord_Key { get; private set; } public Dictionary> JobReplaceIdDict = new Dictionary>(); public Dictionary showCoinUIDict { get; private set; } public int storeTrailerLv { get; private set; } public int fairyStoreJumpShopId = 0; int m_SelectClassifyId = 0; public int selectSecondType { get { return m_SelectClassifyId; } set { if (m_SelectClassifyId != value) { m_SelectClassifyId = value; if (selectClassifyRefresh != null) { selectClassifyRefresh(); } } } } public event Action selectClassifyRefresh; private bool isUpdatePlayerLv; //排行榜活动的商店 public int rankActStore_MoneyType; public int rankActStore_StoreType; public Operation rankActStore_ActType; public override void Init() { ParseFuncConfig(); ParseStoreConfig(); SetShopRedpoint(); } public void OnBeforePlayerDataInitialize() { isUpdatePlayerLv = false; IsMustBuyDay = false; sortStoreSecondType = true; ClearJump(); FuncOpen.Instance.OnFuncStateChangeEvent -= FuncStateChange; PlayerDatas.Instance.fairyData.OnRefreshFairyMine -= RefreshServerHour; PlayerDatas.Instance.fairyData.OnRefreshFairyInfo -= RefreshFamilyLv; PlayerDatas.Instance.playerDataRefreshEvent -= RefreshPlayerData; TimeMgr.Instance.OnHourEvent -= RefreshServerHour; GlobalTimeEvent.Instance.secondEvent -= UpdateSecond; shopItemlimitDict.Clear(); storeFuncType = StoreFunc.DayStore; } public void OnAfterPlayerDataInitialize() { UNIONSTORESAVE_KEY = StringUtility.Contact(PlayerDatas.Instance.baseData.PlayerID, LocalSaveStoreType.UnionStore); StoreEffectRecord_Key = StringUtility.Contact(PlayerDatas.Instance.baseData.PlayerID, "StoreEffectRecord"); MUSTBUYSAVE_KEY = StringUtility.Contact(PlayerDatas.Instance.baseData.PlayerID, "MustBuy"); buyItemCheckDict.Clear(); } public void OnPlayerLoginOk() { PlayerDatas.Instance.fairyData.OnRefreshFairyInfo += RefreshFamilyLv; PlayerDatas.Instance.fairyData.OnRefreshFairyMine += RefreshServerHour; FuncOpen.Instance.OnFuncStateChangeEvent += FuncStateChange; PlayerDatas.Instance.playerDataRefreshEvent += RefreshPlayerData; TimeMgr.Instance.OnHourEvent += RefreshServerHour; GlobalTimeEvent.Instance.secondEvent += UpdateSecond; UpdateShowStore(); SetIsMustBuyDay(); ControllerRedPoint(); UpdateFreeShopRedpoint(); UpdateCanBuyRedpoint(); UpdateMustBuyRedpoint(); UpdateDailyRedpoinit(); } #region 解析本地数据 public Dictionary> storeRedRuleDict { get; private set; } //红点类型 1,免费商品 2,必买商品 3,坐骑灵宠 4,可购买物品(积分兑换) private void ParseFuncConfig() { storeRedRuleDict = new Dictionary>(); FuncConfigConfig storeRedRules = FuncConfigConfig.Get("StoreRedRules"); if (storeRedRules != null) { JsonData redRules = JsonMapper.ToObject(storeRedRules.Numerical1); foreach (var type in redRules.Keys) { int redType = 0; int.TryParse(type, out redType); JsonData shops = redRules[type]; if (!storeRedRuleDict.ContainsKey(redType)) { List shopIdlist = new List(); if (shops.IsArray) { for (int i = 0; i < shops.Count; i++) { int shopId = 0; int.TryParse(shops[i].ToString(), out shopId); shopIdlist.Add(shopId); } } storeRedRuleDict.Add(redType, shopIdlist); } } } } public Dictionary> storeTypeDict { get; private set; } public Dictionary> theOnlyShopDict { get; private set; } //key 物品id public Dictionary> limitValueShopDict { get; private set; } //key 商品类型和限制条件 private void ParseStoreConfig() { storeTypeDict = new Dictionary>(); theOnlyShopDict = new Dictionary>(); limitValueShopDict = new Dictionary>(); List storeConfigs = StoreConfig.GetValues(); for (int i = 0; i < storeConfigs.Count; i++) { var config = storeConfigs[i]; if (config.ShopType != 0) { StoreData storeData = new StoreData(); storeData.shopId = config.ID; storeData.storeConfig = config; storeData.jobReplaceDict = AnalysisJobReplace(config); if (!storeTypeDict.ContainsKey(config.ShopType)) { List storeDatas = new List(); storeDatas.Add(storeData); storeTypeDict.Add(config.ShopType, storeDatas); } else { storeTypeDict[config.ShopType].Add(storeData); } if (config.TheOnlyShop == 1) { if (!theOnlyShopDict.ContainsKey(config.ItemID)) { List storeDatas = new List(); storeDatas.Add(storeData); theOnlyShopDict.Add(config.ItemID, storeDatas); } else { theOnlyShopDict[config.ItemID].Add(storeData); } } string key = StringUtility.Contact(config.ShopType, config.LimitValue); if (!limitValueShopDict.ContainsKey(key)) { List storeDatas = new List(); storeDatas.Add(storeData); limitValueShopDict.Add(key, storeDatas); } else { limitValueShopDict[key].Add(storeData); } } } foreach (var type in storeTypeDict.Keys) { var configs = storeTypeDict[type]; configs.Sort(CompareByShopSort); } } private Dictionary> AnalysisJobReplace(StoreConfig storeConfig) { if (storeConfig == null || string.IsNullOrEmpty(storeConfig.JobItem)) return null; Dictionary> replaceDict = new Dictionary>(); JsonData jsonData = JsonMapper.ToObject(storeConfig.JobItem); if (jsonData.IsArray) { for (int i = 0; i < jsonData.Count; i++) { List idlist = new List(); replaceDict.Add(i, idlist); if (jsonData[i].IsArray) { for (int j = 0; j < jsonData[i].Count; j++) { int itemId = int.Parse(jsonData[i][j].ToString()); idlist.Add(itemId); } } } } return replaceDict; } public int CompareByShopSort(StoreData start, StoreData end) { int sort1 = start.storeConfig.ShopSort; int sort2 = end.storeConfig.ShopSort; return sort1.CompareTo(sort2); } public class StoreData { public int shopId; public StoreConfig storeConfig; public Dictionary> jobReplaceDict; } #endregion #region 获取数据 private Dictionary> showStoreTypeDict = new Dictionary>(); private Dictionary>> showStoreSecondTypeDict = new Dictionary>>(); // 新规则分二级标签,此函数保留,另增加UpdateShowStoreEx函数 public void UpdateShowStore() { showStoreTypeDict.Clear(); int playeLv = PlayerDatas.Instance.baseData.LV; //int vipLevel = PlayerDatas.Instance.baseData.VIPLv; foreach (var type in storeTypeDict.Keys) { var storeDatas = storeTypeDict[type]; List showStoreDatas = new List(); if (!showStoreTypeDict.ContainsKey(type)) { for (int i = 0; i < storeDatas.Count; i++) { var storeData = storeDatas[i]; bool isReachLv = playeLv >= storeData.storeConfig.LVSee ? true : false; bool isReach = isReachLv; if (isReach) { int remainNum = 0; bool isSellOut = TryGetIsSellOut(storeData.storeConfig, out remainNum); if (storeData.storeConfig.IsHideSellOut != 1) { showStoreDatas.Add(storeData); } else { if (storeData.storeConfig.TheOnlyShop == 1) { if (!CheckTheOnlyShopSellOut(storeData.shopId)) { showStoreDatas.Add(storeData); } } else { if (!isSellOut) { showStoreDatas.Add(storeData); } } } } } showStoreTypeDict.Add(type, showStoreDatas); } } UpdateShowStoreEx(); } // 商城分二级标签 public void UpdateShowStoreEx() { sortStoreSecondType = true; showStoreSecondTypeDict.Clear(); foreach (var type in showStoreTypeDict.Keys) { if (!showStoreSecondTypeDict.ContainsKey(type)) showStoreSecondTypeDict[type] = new Dictionary>(); foreach (var storeData in showStoreTypeDict[type]) { foreach (var secondType in storeData.storeConfig.SecondType) { if (!showStoreSecondTypeDict[type].ContainsKey(secondType)) showStoreSecondTypeDict[type][secondType] = new List(); showStoreSecondTypeDict[type][secondType].Add(storeData); } } } } bool sortStoreSecondType = true; public void SortStoreSecondType() { //ArrayList lst = new ArrayList(showStoreSecondTypeDict.Keys); if (!sortStoreSecondType) return; foreach (var type in showStoreSecondTypeDict.Keys) { foreach (var secondType in showStoreSecondTypeDict[type].Keys) { var storeList = showStoreSecondTypeDict[type][secondType]; storeList.Sort(CompareSecondShop); } } sortStoreSecondType = false; } private bool IsSellOut(StoreData storeData) { int remainNum = 0; if (TryGetIsSellOut(storeData.storeConfig, out remainNum)) return true; if (storeData.storeConfig.TheOnlyShop == 1 && CheckTheOnlyShopSellOut(storeData.shopId)) return true; return false; } private int CompareSecondShop(StoreData start, StoreData end) { bool isSellOut1 = IsSellOut(start); bool isSellOut2 = IsSellOut(end); if (isSellOut1 != isSellOut2) return isSellOut1.CompareTo(isSellOut2); int sort1 = start.storeConfig.ShopSort; int sort2 = end.storeConfig.ShopSort; return sort1.CompareTo(sort2); } /// /// 检测唯一商品是否已售罄 /// /// /// /// public bool CheckTheOnlyShopSellOut(int shopIndex) { StoreConfig storeConfig = StoreConfig.Get(shopIndex); if (storeConfig == null || storeConfig.TheOnlyShop != 1) return false; if (theOnlyShopDict.ContainsKey(storeConfig.ItemID)) { List datas = theOnlyShopDict[storeConfig.ItemID]; for (int i = 0; i < datas.Count; i++) { var data = datas[i]; int remainNum = 0; if (TryGetIsSellOut(data.storeConfig, out remainNum)) { return true; } } } return false; } public List TryGetStoreDatas(StoreFunc type) { var results = new List(); List datas = null; if (showStoreTypeDict.TryGetValue((int)type, out datas)) { results.AddRange(datas); //switch (type) //{ // case StoreFunc.MysteryStore: // foreach (var item in datas) // { // if (mysteryCommondities.Contains(item.storeConfig.ID)) // { // results.Add(item); // } // } // results.Sort((StoreData x, StoreData y) => { return x.storeConfig.MoneyType < y.storeConfig.MoneyType ? -1 : 1; }); // break; // default: // results.AddRange(datas); // break; //} } return results; } // 获取二级标签商品 public List TryGetStoreDatasBySecondType(int type, int secondType) { if (!showStoreSecondTypeDict.ContainsKey(type)) return null; if (!showStoreSecondTypeDict[type].ContainsKey(secondType)) return null; SortStoreSecondType(); return showStoreSecondTypeDict[type][secondType]; } // 获得二级标签的第一个标签类型 public int GetFirstStoreSecondType(int type, bool jump = true) { if (jump && jumpToItemId != 0) { if (selectSecondType == 0) selectSecondType = 1; return selectSecondType; } if (!showStoreSecondTypeDict.ContainsKey(type)) return 1; ArrayList sortList = new ArrayList(showStoreSecondTypeDict[type].Keys); sortList.Sort(); return (int)sortList[0]; } // 获得二级标签的第一个标签类型 public ArrayList GetStoreSecondTypeList(int type) { if (!showStoreSecondTypeDict.ContainsKey(type)) return null; ArrayList sortList = new ArrayList(showStoreSecondTypeDict[type].Keys); sortList.Sort(); return sortList; } public StoreData GetStoreData(int shopId) { StoreConfig storeConfig = StoreConfig.Get(shopId); if (storeConfig == null) return null; List storeDatas = null; storeTypeDict.TryGetValue(storeConfig.ShopType, out storeDatas); if (storeDatas != null) { for (int i = 0; i < storeDatas.Count; i++) { var storeData = storeDatas[i]; if (storeData.shopId == shopId) { return storeData; } } } return null; } // 不同职业显示不同物品的情况 public int GetReplaceId(int shopId, int itemId) { var storeData = GetStoreData(shopId); if (storeData == null) return 0; int job = PlayerDatas.Instance.baseData.Job; var replaceDict = storeData.jobReplaceDict; if (replaceDict != null) { foreach (var index in replaceDict.Keys) { var idlist = replaceDict[index]; if (idlist.Contains(itemId)) { int replaceIndex = job - 1; return idlist[replaceIndex]; } } } return itemId; } public bool TryGetRedTypeByShopId(int shopId, out int type) { type = 0; foreach (var key in storeRedRuleDict.Keys) { List idlist = storeRedRuleDict[key]; if (idlist.Contains(shopId)) { type = key; return true; } } return false; } public bool TryGetIsSellOut(StoreConfig storeConfig, out int remainCnt) { int canBuyCnt = 0; int addBuyCnt = 0; remainCnt = 0; bool isLimitBuy = TryGetLimitBuy(storeConfig, out canBuyCnt, out addBuyCnt); if (!isLimitBuy) return false; remainCnt = canBuyCnt; BuyShopItemLimit shopItemLimit = GetBuyShopLimit((uint)storeConfig.ID); if (shopItemLimit != null) { remainCnt -= shopItemLimit.BuyCnt; } if (remainCnt <= 0) { return true; } return false; } /// /// /// /// /// 可购买上限 /// 下一级VIP增加的可购买次数 /// public bool TryGetLimitBuy(StoreConfig config, out int canBuyCnt, out int addBuyCnt) { canBuyCnt = 0; addBuyCnt = 0; if (config == null) return false; int[] canBuyNums = config.GoumaiNumber; if (canBuyNums == null || canBuyNums.Length < 1) return false; int curVipIndex = -1; int nexVipIndex = -1; bool isVipBuy = TryGetVipBuy(config, out curVipIndex, out nexVipIndex); if (isVipBuy) { if (curVipIndex != -1) { canBuyCnt = canBuyNums[curVipIndex]; } if (nexVipIndex != -1) { addBuyCnt = canBuyNums[nexVipIndex] - canBuyCnt; } return true; } else { if (canBuyNums[0] != 0) { canBuyCnt = canBuyNums[0]; return true; } else { return false; } } } public bool TryGetVipBuy(StoreConfig config, out int curVipIndex, out int nextVipIndex) { curVipIndex = -1; nextVipIndex = -1; bool isVipBuy = false; if (config == null) return false; var vipLvs = config.VIPLV; if (vipLvs == null || vipLvs.Length < 1) return false; for (int i = 0; i < vipLvs.Length; i++) { var vipLv = vipLvs[i]; if (vipLv != 0) { isVipBuy = true; } } if (isVipBuy) { int playerVip = PlayerDatas.Instance.baseData.VIPLv; for (int i = vipLvs.Length - 1; i > -1; i--) { var vipLv = vipLvs[i]; if (vipLv > playerVip) { nextVipIndex = i; } else if (vipLv <= playerVip) { curVipIndex = i; break; } } } return isVipBuy; } public List TryGetStoreDatasByLimit(int type, int limitValue) { string key = StringUtility.Contact(type, limitValue); List datas = null; limitValueShopDict.TryGetValue(key, out datas); return datas; } #endregion public string GetMysteryStoreRefreshTime() { if (GeneralDefine.mysteryShopRefreshInterval == 0) { return ""; } var seconds = GeneralDefine.mysteryShopRefreshInterval - (int)((TimeUtility.ServerNow - TimeUtility.createRoleTime).TotalSeconds) % GeneralDefine.mysteryShopRefreshInterval; return Language.Get("StoreWin200", TimeUtility.SecondsToHMS(seconds)); } private int GetWillRefreshTime() { int willRefresh = (3 - TimeUtility.OpenDay % 3); if (willRefresh == 3) { if (TimeUtility.ServerNow.Hour < 5) { willRefresh = 0; } } int remainHour = 5 - TimeUtility.ServerNow.Hour; int remainMinute = 0 - TimeUtility.ServerNow.Minute; int remainSecond = willRefresh * 24 * 60 * 60 + remainHour * 60 * 60 + remainMinute * 60 - TimeUtility.ServerNow.Second; return remainSecond; } int refreshTime = 0; private void UpdateSecond() { if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.Store)) return; if (isUpdatePlayerLv) { UpdatePlayerLv(); isUpdatePlayerLv = false; } } private void UpdatePlayerLv() { UpdateShowStore(); UpdateFreeShopRedpoint(); UpdateCanBuyRedpoint(); UpdateMustBuyRedpoint(); } private void RefreshPlayerData(PlayerDataType type) { if (type == PlayerDataType.VIPLv) { UpdateShowStore(); } switch (type) { case PlayerDataType.LV: isUpdatePlayerLv = true; break; case PlayerDataType.VIPLv: case PlayerDataType.Gold: case PlayerDataType.GoldPaper: UpdateFreeShopRedpoint(); UpdateCanBuyRedpoint(); UpdateDailyRedpoinit(); break; case PlayerDataType.UnionLiven: UpdateDailyRedpoinit(); break; case PlayerDataType.FBHelpPoint: UpdateFreeShopRedpoint(); UpdateCanBuyRedpoint(); break; } } private void RefreshFamilyLv() { int familyLv = PlayerDatas.Instance.fairyData.fairy.FamilyLV; if (familyLv > GetSaveFairyLV()) { ControllerRedPoint(); } UpdateDailyRedpoinit(); } private void RefreshServerHour() { ControllerRedPoint(); if (PlayerPrefs.HasKey(MUSTBUYSAVE_KEY)) { int[] records = LocalSave.GetIntArray(MUSTBUYSAVE_KEY); if (TimeUtility.ServerNow.Hour >= 5 && ((TimeUtility.ServerNow.Day == records[0] && records[1] < 5) || TimeUtility.ServerNow.Day != records[0])) { saveTimes[0] = TimeUtility.ServerNow.Day; saveTimes[1] = TimeUtility.ServerNow.Hour; IsMustBuyDay = true; LocalSave.SetIntArray(MUSTBUYSAVE_KEY, saveTimes); UpdateMustBuyRedpoint(); } } if (!PlayerDatas.Instance.fairyData.HasFairy) { PlayerPrefs.DeleteKey(UNIONSTORESAVE_KEY); } UpdateDailyRedpoinit(); } public event Action RefreshBuyShopLimitEvent; public StoreFunc storeFuncType = StoreFunc.DayStore; public int jumpStoreFuncType { get; set; } private Dictionary shopItemlimitDict = new Dictionary(); /// /// 得到物品购买次数 /// /// public void RefreshBuyShopLimitModel(HA802_tagMCShopItemDayBuyCntInfo buylimit) { Debug.Log("RefreshBuyShopLimitModel" + buylimit.Count); if (buylimit.Count > 0) { int i = 0; for (i = 0; i < buylimit.Count; i++) { if (!shopItemlimitDict.ContainsKey(buylimit.DayBuyCntList[i].ItemIndex)) { BuyShopItemLimit shopItemLimit = new BuyShopItemLimit(); shopItemLimit.ItemIndex = buylimit.DayBuyCntList[i].ItemIndex; shopItemLimit.BuyCnt = (int)buylimit.DayBuyCntList[i].BuyCnt; shopItemLimit.isReset = buylimit.DayBuyCntList[i].IsReset; shopItemlimitDict.Add(shopItemLimit.ItemIndex, shopItemLimit); } else { shopItemlimitDict[buylimit.DayBuyCntList[i].ItemIndex].BuyCnt = (int)buylimit.DayBuyCntList[i].BuyCnt; shopItemlimitDict[buylimit.DayBuyCntList[i].ItemIndex].isReset = buylimit.DayBuyCntList[i].IsReset; } } } sortStoreSecondType = true; UpdateShowStore(); UpdateFreeShopRedpoint(); UpdateCanBuyRedpoint(); UpdateMustBuyRedpoint(); UpdateDailyRedpoinit(); if (RefreshBuyShopLimitEvent != null) RefreshBuyShopLimitEvent(); } public BuyShopItemLimit GetBuyShopLimit(uint itemIndex) { if (shopItemlimitDict.ContainsKey(itemIndex)) { return shopItemlimitDict[itemIndex]; } return null; } //和GetShopItemlistEx 一样 获取商店物品列表,只是返回类型不同 List shopItemlist = new List(); public List GetShopItemlistByIndex(StoreConfig storeConfig) { if (storeConfig == null) return null; shopItemlist.Clear(); if (storeConfig.ItemID != 0) { int replaceId = GetReplaceId(storeConfig.ID, storeConfig.ItemID); ShopItemInfo shopItem = new ShopItemInfo(replaceId, storeConfig.ItemCnt); shopItemlist.Add(shopItem); } JsonData extraItem = JsonMapper.ToObject(storeConfig.ItemListEx); if (extraItem.IsArray) { for (int i = 0; i < extraItem.Count; i++) { if (extraItem[i].IsArray) { if (extraItem[i].Count > 0) { int itemId = int.Parse(extraItem[i][0].ToString()); int itemCount = int.Parse(extraItem[i][1].ToString()); if (itemId != 0) { int extraReplaceId = GetReplaceId(storeConfig.ID, itemId); ShopItemInfo shop = new ShopItemInfo(extraReplaceId, itemCount); shopItemlist.Add(shop); } } } } } return shopItemlist; } //和GetShopItemlistByIndex 一样 获取商店物品列表,只是返回类型不同 public List GetShopItemlistEx(StoreConfig storeConfig) { if (storeConfig == null) return null; List shopItemlist = new List(); if (storeConfig.ItemID != 0) { int replaceId = GetReplaceId(storeConfig.ID, storeConfig.ItemID); shopItemlist.Add(new int[] { replaceId, storeConfig.ItemCnt, 0 }); } var extraItem = JsonMapper.ToObject(storeConfig.ItemListEx); for (int i = 0; i < extraItem.Length; i++) { shopItemlist.Add(extraItem[i]); } return shopItemlist; } public bool TryGetShopItemInfo(StoreFunc _type, int _id, out List _shopItems) { _shopItems = null; var _list = TryGetStoreDatas(_type); var _index = _list.FindIndex((x) => { return x.shopId == _id; }); if (_index == -1) { return false; } _shopItems = GetShopItemlistByIndex(_list[_index].storeConfig); return _shopItems != null; } #region 点击商店物品逻辑 public void OnClickShopCell(StoreConfig shopInfo) { int itemId = GetReplaceId(shopInfo.ID, shopInfo.ItemID); ItemTipUtility.ShowGood(shopInfo.ID, itemId); } public int BuyCnt { get; private set; } public void SetBuyCnt(int buyCnt) { BuyCnt = buyCnt; } #endregion private ulong _price; public void SendBuyShopItem(StoreConfig model, int count) { _price = (ulong)(model.MoneyNumber * count); if (MoneyIsEnough(model.MoneyType, _price)) { var vipLv = PlayerDatas.Instance.baseData.VIPLv; var itemMinLv = model.VIPLV[0]; if (vipLv < itemMinLv) { SysNotifyMgr.Instance.ShowTip("VIPNotEnough", itemMinLv); } else { CA310_tagCMBuyItem buyShop = new CA310_tagCMBuyItem(); buyShop.BuyItemIndex = (ushort)model.ID; buyShop.BuyCount = (uint)count; GameNetSystem.Instance.SendInfo(buyShop); } } else { switch (model.MoneyType) { case 1: if (VersionConfig.Get().isBanShu) { SysNotifyMgr.Instance.ShowTip("GoldErr"); return; } // WindowCenter.Instance.Open(); break; case 25: SysNotifyMgr.Instance.ShowTip("LackXBMoney", model.MoneyType); break; default: SysNotifyMgr.Instance.ShowTip("LackMoney", model.MoneyType); break; } } } //仙玉购买物品的二次确认框,一级货币只有仙玉 默认为仙玉即可 Dictionary buyItemCheckDict = new Dictionary(); //type 对应枚举 BuyStoreItemCheckType 方便记忆 public void SendBuyShopItemWithPopCheck(StoreConfig model, int count, int type = 0) { if (model.MoneyNumber == 0) { //免费的 SendBuyShopItem(model, count); return; } if (buyItemCheckDict.ContainsKey(type) && buyItemCheckDict[type]) { SendBuyShopItem(model, count); return; } ConfirmCancel.ToggleConfirmCancel(Language.Get("Mail101"), Language.Get("OSTimeLimitGiftConfirm", model.MoneyNumber), Language.Get("ConfirmCancel102"), (Action)((bool isOk, bool isToggle) => { if (isOk) { SendBuyShopItem(model, count); buyItemCheckDict[type] = isToggle; } })); } //花仙玉购买的二次确认框(本次登录) 默认提示 MysticalQG104 是否花费{0}仙玉进行购买? //type 对应枚举 BuyStoreItemCheckType 方便记忆 public void UseMoneyCheck(int money, Action func, int type = 0, string tip = "MysticalQG104", string fullTip = "") { if (money == 0) { //免费的 func?.Invoke(); return; } if (buyItemCheckDict.ContainsKey(type) && buyItemCheckDict[type]) { func?.Invoke(); return; } ConfirmCancel.ToggleConfirmCancel(Language.Get("Mail101"), fullTip == "" ? Language.Get(tip, money) : fullTip, Language.Get("ConfirmCancel102"), (bool isOk, bool isToggle) => { if (isOk) { func?.Invoke(); buyItemCheckDict[type] = isToggle; } }); } public event Action RefreshBuyResultEvent; public void GetBuyResult(HA811_tagMCShoppingResult result) { //Debug.Log("GetBuyResult"); StoreConfig tagStore = StoreConfig.Get((int)result.ItemIndex); if (tagStore != null) { ItemConfig chinModel = ItemConfig.Get(GetReplaceId(tagStore.ID, tagStore.ItemID)); if (tagStore.RemindSuccess == 0) { return; } if (RefreshBuyResultEvent != null) { RefreshBuyResultEvent(chinModel.ID); } } } public bool MoneyIsEnough(int moneyType, ulong money) { if (UIHelper.GetMoneyCnt(moneyType) < money) { return false; } else { return true; } } public int funcOrder { get; private set; } public int jumpToItemId { get; set; } /// /// 会先清之前的跳转,调用者要注意 ClearJump /// /// public void SetJumpToModel(int itemId) { ClearJump(); jumpToItemId = itemId; } public void ClearJump() { funcOrder = -1; jumpToItemId = 0; } public void SetWinOrder(int order) { funcOrder = order; } public void OpenStoreWin(bool forceSync = false, int functionOrder = 0, bool useJump = false) { if (useJump && funcOrder != -1) { // WindowCenter.Instance.Open(forceSync, funcOrder); } else { ClearJump(); // WindowCenter.Instance.Open(forceSync, functionOrder); } } public event Action StoreFuncOpenAct; private void FuncStateChange(int funcId) { switch ((FuncOpenEnum)funcId) { case FuncOpenEnum.Store: if (StoreFuncOpenAct != null) { StoreFuncOpenAct(); } UpdateFreeShopRedpoint(); UpdateCanBuyRedpoint(); UpdateMustBuyRedpoint(); UpdateDailyRedpoinit(); break; case FuncOpenEnum.BlastFurnace: ControllerRedPoint(); break; } } public bool IsNewDay(string recordKey) { if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.Store)) return false; if (PlayerPrefs.HasKey(recordKey)) { int day = LocalSave.GetInt(recordKey); if (day != TimeUtility.ServerNow.Day) { LocalSave.SetInt(recordKey, TimeUtility.ServerNow.Day); return true; } else { return false; } } else { LocalSave.SetInt(recordKey, TimeUtility.ServerNow.Day); return true; } } public bool IsRequireDailyRedRemind(int shopId) { var config = StoreConfig.Get(shopId); if (config == null) { return false; } var key = StringUtility.Contact("Store_", config.ShopType, "_", "Daily", shopId); var array = LocalSave.GetIntArray(key); if (array != null && array.Length == 2) { if (array[0] < TimeUtility.Day - 1) { return true; } else if (array[0] == TimeUtility.Day - 1) { return array[1] < 5 || TimeUtility.Hour >= 5; } else if (array[0] == TimeUtility.Day) { return array[1] < 5 && TimeUtility.Hour >= 5; } } return true; } public void SetDailyRedRedmind(int shopId) { var config = StoreConfig.Get(shopId); if (config == null) { return; } var key = StringUtility.Contact("Store_", config.ShopType, "_", "Daily", shopId); LocalSave.SetIntArray(key, new int[2] { TimeUtility.Day, TimeUtility.Hour }); UpdateDailyRedpoinit(); } #region 商城红点 #region 仙盟红点逻辑处理 private bool CheckIsBuyNewItem(int fairyLv) { if (fairyLv > GetSaveFairyLV()) { var toolStoreDatas = TryGetStoreDatasByLimit((int)StoreFunc.ToolStore, fairyLv); var mountStoreDatas = TryGetStoreDatasByLimit((int)StoreFunc.MountStoneStore, fairyLv); var skillBookStoreData = TryGetStoreDatasByLimit((int)StoreFunc.MountSkillBookStore, fairyLv); if ((toolStoreDatas != null && toolStoreDatas.Count > 0) || (mountStoreDatas != null && mountStoreDatas.Count > 0) || (skillBookStoreData != null && skillBookStoreData.Count > 0)) { return true; } } return false; } private bool CheckIsNewMonth() { GetSaveDateTime(); if (datelist.Count > 0) { if (TimeUtility.ServerNow.Month == datelist[0]) { if (TimeUtility.ServerNow.Day >= 1 && TimeUtility.ServerNow.Hour >= 5 && datelist[1] <= 1 && datelist[2] < 5) { return true; } } else { if (TimeUtility.ServerNow.Day >= 1 && TimeUtility.ServerNow.Hour >= 5) { return true; } } } return false; } List datelist = new List(); public List GetSaveDateTime() { datelist.Clear(); int[] unionArray = LocalSave.GetIntArray(UNIONSTORESAVE_KEY); if (unionArray != null && unionArray.Length >= 4) { datelist.Add(unionArray[1]); datelist.Add(unionArray[2]); datelist.Add(unionArray[3]); } return datelist; } public int GetSaveFairyLV() { int[] unionArray = LocalSave.GetIntArray(UNIONSTORESAVE_KEY); int fairyLv = 0; if (unionArray != null) { return unionArray[0]; } return fairyLv; } //1仙盟等级 2 月份 3 号 4 几点 public void SetStoreLocalSave(LocalSaveStoreType saveStoreType, params int[] infos) { string key = StringUtility.Contact(PlayerDatas.Instance.baseData.PlayerID, saveStoreType); LocalSave.SetIntArray(key, infos); } public void ControllerRedPoint(bool isLook = false) { fairyStoreRemindRedpoint.state = RedPointState.None; if (!FairyModel.Instance.fairyStoreOpen || !FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.BlastFurnace)) { return; } int familyLv = PlayerDatas.Instance.fairyData.fairy.FamilyLV; if (!isLook) { if (CheckIsBuyNewItem(familyLv)) { fairyStoreRemindRedpoint.state = RedPointState.Simple; return; } if (CheckIsNewMonth()) { fairyStoreRemindRedpoint.state = RedPointState.Simple; return; } } SetStoreLocalSave(LocalSaveStoreType.UnionStore, familyLv, TimeUtility.ServerNow.Month, TimeUtility.ServerNow.Day, TimeUtility.ServerNow.Hour); } #endregion public const int StoreFunc_RedKey = 22; public const int StoreFunc1_RedKey = 2201; public const int StoreFunc2_RedKey = 2202; public const int StoreFunc3_RedKey = 2203; public const int StoreFunc4_RedKey = 2204; public const int StoreFunc5_RedKey = 2205; public const int StoreFunc8_RedKey = 2208; public const int FairyStoreRemind_RedKey = 107010601; public Redpoint storeFuncPoint = new Redpoint(StoreFunc_RedKey); public Redpoint storeFunc1Point = new Redpoint(StoreFunc_RedKey, StoreFunc1_RedKey); public Redpoint storeFunc2Point = new Redpoint(StoreFunc_RedKey, StoreFunc2_RedKey); public Redpoint storeFunc3Point = new Redpoint(StoreFunc_RedKey, StoreFunc3_RedKey); public Redpoint storeFunc4Point = new Redpoint(StoreFunc_RedKey, StoreFunc4_RedKey); public Redpoint storeFunc5Point = new Redpoint(StoreFunc_RedKey, StoreFunc5_RedKey); public Redpoint storeFunc8Point = new Redpoint(MainRedDot.FAIRYStore_REDPOINT_KEY3, StoreFunc8_RedKey); public Redpoint fairyStoreRemindRedpoint = new Redpoint(MainRedDot.FAIRYStore_REDPOINT_KEY3, FairyStoreRemind_RedKey); public Dictionary shopRedDict = new Dictionary(); public void SetShopRedpoint() { shopRedDict.Clear(); List storelist = StoreConfig.GetValues(); for (int i = 0; i < storelist.Count; i++) { StoreConfig storeConfig = storelist[i]; int redKey = 0; Redpoint redpoint = null; switch (storeConfig.ShopType) { //case 1: // redKey = StoreFunc1_RedKey * 10000 + storeConfig.ID; // redpoint = new Redpoint(StoreFunc1_RedKey, redKey); // shopRedDict.Add(storeConfig.ID, redpoint); // break; //case 2: // redKey = StoreFunc2_RedKey * 10000 + storeConfig.ID; // redpoint = new Redpoint(StoreFunc2_RedKey, redKey); // shopRedDict.Add(storeConfig.ID, redpoint); // break; //case 3: // redKey = StoreFunc3_RedKey * 10000 + storeConfig.ID; // redpoint = new Redpoint(StoreFunc3_RedKey, redKey); // shopRedDict.Add(storeConfig.ID, redpoint); // break; //case 4: // redKey = StoreFunc4_RedKey * 10000 + storeConfig.ID; // redpoint = new Redpoint(StoreFunc4_RedKey, redKey); // shopRedDict.Add(storeConfig.ID, redpoint); // break; //case 5: // redKey = StoreFunc5_RedKey * 10000 + storeConfig.ID; // redpoint = new Redpoint(StoreFunc5_RedKey, redKey); // shopRedDict.Add(storeConfig.ID, redpoint); // break; case 8: redKey = StoreFunc8_RedKey * 10000 + storeConfig.ID; redpoint = new Redpoint(StoreFunc8_RedKey, redKey); shopRedDict.Add(storeConfig.ID, redpoint); break; } } } public void UpdateFreeShopRedpoint() { if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.Store)) return; foreach (var key in showStoreTypeDict.Keys) { var storeDatas = showStoreTypeDict[key]; for (int i = 0; i < storeDatas.Count; i++) { var storeConfig = storeDatas[i].storeConfig; int type = 0; TryGetRedTypeByShopId(storeConfig.ID, out type); if (type == 1) { int remainNum = 0; if (shopRedDict.ContainsKey(storeConfig.ID)) { if (!TryGetIsSellOut(storeConfig, out remainNum)) { shopRedDict[storeConfig.ID].state = RedPointState.Simple; } else { shopRedDict[storeConfig.ID].state = RedPointState.None; } } } } } } public void UpdateCanBuyRedpoint() { if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.Store)) return; foreach (var key in showStoreTypeDict.Keys) { var storeDatas = showStoreTypeDict[key]; for (int i = 0; i < storeDatas.Count; i++) { var storeConfig = storeDatas[i].storeConfig; int type = 0; TryGetRedTypeByShopId(storeConfig.ID, out type); if (type == 4) { int remainNum = 0; if (shopRedDict.ContainsKey(storeConfig.ID)) { if (!TryGetIsSellOut(storeConfig, out remainNum)) { if (UIHelper.GetMoneyCnt(storeConfig.MoneyType) >= (ulong)storeConfig.MoneyNumber) { shopRedDict[storeConfig.ID].state = RedPointState.Simple; } else { shopRedDict[storeConfig.ID].state = RedPointState.None; } } else { shopRedDict[storeConfig.ID].state = RedPointState.None; } } } } } } public void UpdateMustBuyRedpoint() { if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.Store)) return; foreach (var key in showStoreTypeDict.Keys) { var storeDatas = showStoreTypeDict[key]; for (int i = 0; i < storeDatas.Count; i++) { var storeConfig = storeDatas[i].storeConfig; int type = 0; TryGetRedTypeByShopId(storeConfig.ID, out type); if (type == 2) { if (shopRedDict.ContainsKey(storeConfig.ID)) { if (CheckIsMustBuy(storeConfig)) { shopRedDict[storeConfig.ID].state = RedPointState.Simple; } else { shopRedDict[storeConfig.ID].state = RedPointState.None; } } } } } } public void UpdateDailyRedpoinit() { if (storeRedRuleDict.ContainsKey(6)) { var shopIds = storeRedRuleDict[6]; var count = 0; foreach (var shopId in shopIds) { var redable = false; var config = StoreConfig.Get(shopId); if (config == null) { Debug.LogError($"StoreConfig {shopId} is null"); continue; } switch (config.ShopType) { case 8: if (TryGetIsSellOut(config, out count)) { break; } if (PlayerDatas.Instance.fairyData.fairy == null) { break; } if (config.VIPLV.Length > 0 && PlayerDatas.Instance.baseData.VIPLv < config.VIPLV[0]) { break; } if (PlayerDatas.Instance.fairyData.fairy.FamilyLV < config.LimitValue) { break; } if (!MoneyIsEnough(config.MoneyType, (ulong)config.MoneyNumber)) { break; } redable = IsRequireDailyRedRemind(shopId); break; } if (shopRedDict.ContainsKey(shopId)) { shopRedDict[shopId].state = redable ? RedPointState.Simple : RedPointState.None; } } } } public void ClearMustBuyRedpoint(StoreConfig storeConfig) { if (!shopRedDict.ContainsKey(storeConfig.ID)) return; int type = 0; TryGetRedTypeByShopId(storeConfig.ID, out type); if (type == 2) { shopRedDict[storeConfig.ID].state = RedPointState.None; IsMustBuyDay = false; } else if (type == 1) { shopRedDict[storeConfig.ID].state = RedPointState.None; } } public bool IsMustBuyDay { get; private set; } int[] saveTimes = new int[2]; public void SetIsMustBuyDay() { if (IsMustBuyDay) return; saveTimes[0] = TimeUtility.ServerNow.Day; saveTimes[1] = TimeUtility.ServerNow.Hour; if (PlayerPrefs.HasKey(MUSTBUYSAVE_KEY)) { int[] records = LocalSave.GetIntArray(MUSTBUYSAVE_KEY); if (TimeUtility.ServerNow.Hour >= 5 && ((TimeUtility.ServerNow.Day == records[0] && records[1] < 5) || TimeUtility.ServerNow.Day != records[0])) { IsMustBuyDay = true; LocalSave.SetIntArray(MUSTBUYSAVE_KEY, saveTimes); } else { IsMustBuyDay = false; } } else { IsMustBuyDay = true; LocalSave.SetIntArray(MUSTBUYSAVE_KEY, saveTimes); } } public bool CheckIsMustBuy(StoreConfig config) { int remainNum = 0; if (!TryGetIsSellOut(config, out remainNum) && IsMustBuyDay) { return true; } return false; } public void ClearPetAndMountRedpoint(StoreConfig storeConfig) { ItemConfig itemConfig = ItemConfig.Get(storeConfig.ItemID); switch (itemConfig.Type) { case 26: case 41: string key = StringUtility.Contact(PlayerDatas.Instance.baseData.PlayerID, "ShopId", storeConfig.ID); if (shopRedDict.ContainsKey(storeConfig.ID) && shopRedDict[storeConfig.ID].state == RedPointState.Simple) { shopRedDict[storeConfig.ID].state = RedPointState.None; LocalSave.SetBool(key, false); } break; } } public void ClearAllPetAndMountRedpoint(StoreFunc storeFunc) { if (storeFuncType == StoreFunc.BindStore && storeFunc != StoreFunc.BindStore) { foreach (var key in shopRedDict.Keys) { StoreConfig storeConfig = StoreConfig.Get(key); ItemConfig itemConfig = ItemConfig.Get(storeConfig.ItemID); switch (itemConfig.Type) { case 26: case 41: if (shopRedDict.ContainsKey(key) && shopRedDict[key].state != RedPointState.None) { string record = StringUtility.Contact(PlayerDatas.Instance.baseData.PlayerID, "ShopId", key); shopRedDict[key].state = RedPointState.None; LocalSave.SetBool(record, false); } break; } } } } public void CloseRedPoint(StoreConfig storeConfig) { ClearMustBuyRedpoint(storeConfig); ClearPetAndMountRedpoint(storeConfig); } public void CloseAllRedpoint(StoreFunc storeFunc) { ClearAllPetAndMountRedpoint(storeFunc); } #endregion } public enum StoreFunc { DayStore = 1, //1:每天限购 CommonStore = 2, //2:幻境阁商店 GrowStrongerStore = 3, //3:成长变强 BindStore = 4, //4:绑玉商城 IntegralStore = 5, //5:积分商城 BagStore = 6, //6:随身商店 RuneStore = 7, //7:符印商店 ToolStore = 8, // 道具商店 MountStoneStore = 9, //坐骑魂石商店 MountSkillBookStore = 10,//坐骑技能书商店 XBEquipStore = 11, //寻宝装备商店 XBRuneStore = 12, //寻宝符印商店 XBToolStore = 13, //寻宝道具商店 OSGift = 14,//开服礼包 OSTimeLimitGift = 15,//限时特惠 CrossOneVsOneHonor = 17,//荣誉商店 MysteryStore = 18, //1:神秘商店 default1, default2, //时间类活动 - 如boss凭证的商店 20 default3, QCTrainActStore = 306, //骑宠养成活动商店 CelestialPalaceStore = 308, //仙宫商店(天道阁) } public enum LocalSaveStoreType { UnionStore, //仙盟商店 }