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<StoreModel>  
 | 
{  
 | 
  
 | 
    public string UNIONSTORESAVE_KEY { get; private set; }  
 | 
    public string MUSTBUYSAVE_KEY { get; private set; }  
 | 
    public string StoreEffectRecord_Key { get; private set; }  
 | 
    public Dictionary<int, Dictionary<int, int>> JobReplaceIdDict = new Dictionary<int, Dictionary<int, int>>();  
 | 
    public Dictionary<int, int> 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<int, List<int>> storeRedRuleDict { get; private set; } //红点类型 1,免费商品  2,必买商品  3,坐骑灵宠 4,可购买物品(积分兑换)  
 | 
    private void ParseFuncConfig()  
 | 
    {  
 | 
        storeRedRuleDict = new Dictionary<int, List<int>>();  
 | 
        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<int> shopIdlist = new List<int>();  
 | 
                    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<int, List<StoreData>> storeTypeDict { get; private set; }  
 | 
    public Dictionary<int, List<StoreData>> theOnlyShopDict { get; private set; } //key 物品id  
 | 
    public Dictionary<string, List<StoreData>> limitValueShopDict { get; private set; } //key 商品类型和限制条件  
 | 
    private void ParseStoreConfig()  
 | 
    {  
 | 
        storeTypeDict = new Dictionary<int, List<StoreData>>();  
 | 
        theOnlyShopDict = new Dictionary<int, List<StoreData>>();  
 | 
        limitValueShopDict = new Dictionary<string, List<StoreData>>();  
 | 
        List<StoreConfig> 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<StoreData> storeDatas = new List<StoreData>();  
 | 
                    storeDatas.Add(storeData);  
 | 
                    storeTypeDict.Add(config.ShopType, storeDatas);  
 | 
                }  
 | 
                else  
 | 
                {  
 | 
                    storeTypeDict[config.ShopType].Add(storeData);  
 | 
                }  
 | 
  
 | 
                if (config.TheOnlyShop == 1)  
 | 
                {  
 | 
                    if (!theOnlyShopDict.ContainsKey(config.ItemID))  
 | 
                    {  
 | 
                        List<StoreData> storeDatas = new List<StoreData>();  
 | 
                        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<StoreData> storeDatas = new List<StoreData>();  
 | 
                    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<int, List<int>> AnalysisJobReplace(StoreConfig storeConfig)  
 | 
    {  
 | 
        if (storeConfig == null || string.IsNullOrEmpty(storeConfig.JobItem)) return null;  
 | 
  
 | 
        Dictionary<int, List<int>> replaceDict = new Dictionary<int, List<int>>();  
 | 
        JsonData jsonData = JsonMapper.ToObject(storeConfig.JobItem);  
 | 
        if (jsonData.IsArray)  
 | 
        {  
 | 
            for (int i = 0; i < jsonData.Count; i++)  
 | 
            {  
 | 
                List<int> idlist = new List<int>();  
 | 
                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<int, List<int>> jobReplaceDict;  
 | 
    }  
 | 
    #endregion  
 | 
  
 | 
    #region 获取数据  
 | 
  
 | 
    private Dictionary<int, List<StoreData>> showStoreTypeDict = new Dictionary<int, List<StoreData>>();  
 | 
  
 | 
    private Dictionary<int, Dictionary<int, List<StoreData>>> showStoreSecondTypeDict = new Dictionary<int, Dictionary<int, List<StoreData>>>();  
 | 
  
 | 
  
 | 
    // 新规则分二级标签,此函数保留,另增加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<StoreData> showStoreDatas = new List<StoreData>();  
 | 
            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<int, List<StoreData>>();  
 | 
  
 | 
            foreach (var storeData in showStoreTypeDict[type])  
 | 
            {  
 | 
  
 | 
                foreach (var secondType in storeData.storeConfig.SecondType)  
 | 
                {  
 | 
                    if (!showStoreSecondTypeDict[type].ContainsKey(secondType))  
 | 
                        showStoreSecondTypeDict[type][secondType] = new List<StoreData>();  
 | 
  
 | 
                    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);  
 | 
    }  
 | 
  
 | 
    /// <summary>  
 | 
    /// 检测唯一商品是否已售罄  
 | 
    /// </summary>  
 | 
    /// <param name="shopIndex"></param>  
 | 
    /// <param name="isTheOnlyShop"></param>  
 | 
    /// <returns></returns>  
 | 
    public bool CheckTheOnlyShopSellOut(int shopIndex)  
 | 
    {  
 | 
        StoreConfig storeConfig = StoreConfig.Get(shopIndex);  
 | 
        if (storeConfig == null || storeConfig.TheOnlyShop != 1) return false;  
 | 
  
 | 
        if (theOnlyShopDict.ContainsKey(storeConfig.ItemID))  
 | 
        {  
 | 
            List<StoreData> 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<StoreData> TryGetStoreDatas(StoreFunc type)  
 | 
    {  
 | 
        var results = new List<StoreData>();  
 | 
        List<StoreData> 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<StoreData> 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<StoreData> 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<int> 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;  
 | 
    }  
 | 
  
 | 
    /// <summary>  
 | 
    ///   
 | 
    /// </summary>  
 | 
    /// <param name="config"></param>  
 | 
    /// <param name="canBuyCnt"> 可购买上限</param>  
 | 
    /// <param name="addBuyCnt"> 下一级VIP增加的可购买次数</param>  
 | 
    /// <returns></returns>  
 | 
    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<StoreData> TryGetStoreDatasByLimit(int type, int limitValue)  
 | 
    {  
 | 
        string key = StringUtility.Contact(type, limitValue);  
 | 
        List<StoreData> 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<uint, BuyShopItemLimit> shopItemlimitDict = new Dictionary<uint, BuyShopItemLimit>();  
 | 
  
 | 
    /// <summary>  
 | 
    /// 得到物品购买次数  
 | 
    /// </summary>  
 | 
    /// <param name="buylimit"></param>  
 | 
    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<ShopItemInfo> shopItemlist = new List<ShopItemInfo>();  
 | 
    public List<ShopItemInfo> 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<int[]> GetShopItemlistEx(StoreConfig storeConfig)  
 | 
    {  
 | 
        if (storeConfig == null) return null;  
 | 
  
 | 
        List<int[]> shopItemlist = new List<int[]>();  
 | 
        if (storeConfig.ItemID != 0)  
 | 
        {  
 | 
            int replaceId = GetReplaceId(storeConfig.ID, storeConfig.ItemID);  
 | 
            shopItemlist.Add(new int[] { replaceId, storeConfig.ItemCnt, 0 });  
 | 
        }  
 | 
        var extraItem = JsonMapper.ToObject<int[][]>(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<ShopItemInfo> _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.Show(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<RechargeTipWin>();  
 | 
                    break;  
 | 
                case 25:  
 | 
                    SysNotifyMgr.Instance.ShowTip("LackXBMoney", model.MoneyType);  
 | 
                    break;  
 | 
                default:  
 | 
                    SysNotifyMgr.Instance.ShowTip("LackMoney", model.MoneyType);  
 | 
                    break;  
 | 
            }  
 | 
        }  
 | 
  
 | 
    }  
 | 
  
 | 
    //仙玉购买物品的二次确认框,一级货币只有仙玉 默认为仙玉即可  
 | 
    Dictionary<int, bool> buyItemCheckDict = new Dictionary<int, bool>();  
 | 
    //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, bool>)((bool isOk, bool isToggle) =>  
 | 
        {  
 | 
            if (isOk)  
 | 
            {  
 | 
                SendBuyShopItem(model, count);  
 | 
                buyItemCheckDict[type] = isToggle;  
 | 
            }  
 | 
              
 | 
        }));  
 | 
    }  
 | 
  
 | 
    //花仙玉购买的二次确认框(本次登录) 默认提示 MysticalQG104    是否花费<color=#109d06>{0}</color>仙玉进行购买?  
 | 
    //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<int> 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; }  
 | 
  
 | 
    /// <summary>  
 | 
    /// 会先清之前的跳转,调用者要注意 ClearJump  
 | 
    /// </summary>  
 | 
    /// <param name="itemId"></param>  
 | 
    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<StoreWin>(forceSync, funcOrder);  
 | 
        }  
 | 
        else  
 | 
        {   
 | 
            ClearJump();  
 | 
            // WindowCenter.Instance.Open<StoreWin>(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<int> datelist = new List<int>();  
 | 
    public List<int> 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<int, Redpoint> shopRedDict = new Dictionary<int, Redpoint>();  
 | 
    public void SetShopRedpoint()  
 | 
    {  
 | 
        shopRedDict.Clear();  
 | 
        List<StoreConfig> 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, //仙盟商店  
 | 
  
 | 
}  
 | 
  
 |