// *********************************************************************** // Assembly : Game // Author : Kimch // Created : 2020-12-08 // Description : // Last Modified By : // Last Modified On : // *********************************************************************** // // // *********************************************************************** using CodeStage.AntiCheat.ObscuredTypes; using System.Collections; using System.Collections.Generic; using UnityEngine; namespace G { /// /// 宝箱商城 /// public class BoxShopProxy : F.GameProxy { /// /// 道具宝箱 /// public class PropBoxInfo { public readonly ItemShopBox item; public int id => item.id; public int type => item.type; public string name => item.name; /// /// 广告次数Id /// public int adTimeId => item.adTimeId; private Item.ItemInfo[] _unitPrices; /// /// 单价 /// public Item.ItemInfo unitPrice { get { if (keyPrice.id > 0 && MoneyProxy.Instance.CheckMoney(keyPrice.id, 1)) return new Item.ItemInfo { id = keyPrice.id, count = 1 }; int chapterIndex = Mathf.Max(0, LevelProxy.Instance.currentChapterId - 1); return _unitPrices != null && _unitPrices.Length > chapterIndex ? _unitPrices[chapterIndex] : default; } } private ObscuredInt _multiCount; public int multiCount => _multiCount; private Item.ItemInfo[] _multiPrices; /// /// 10次价格 /// public Item.ItemInfo multiPrice { get { if (keyPrice.id > 0 && MoneyProxy.Instance.CheckMoney(keyPrice.id, multiCount)) return new Item.ItemInfo { id = keyPrice.id, count = multiCount }; int index = Mathf.Max(0, LevelProxy.Instance.currentChapterId - 1); return _multiPrices != null && _multiPrices.Length > index ? _multiPrices[index] : default; } } /// /// 钥匙价格 /// public readonly Item.ItemInfo keyPrice; /// /// 开箱间隔 /// public int openInterval => item.openInterval; private int _lastOpenTimestamp; /// /// 开箱(临时保存) /// public int openRemainSeconds { get { return Mathf.Max(0, _lastOpenTimestamp - Launch.Timestamp); } set { _lastOpenTimestamp = Launch.Timestamp + value; } } /// /// 免费间隔 /// public int freeInterval => item.freeTime > 0 ? TimeProxy.Instance.GetRecoverInterval(item.freeTime) : 0; /// /// /// public int freeRemainSeconds { get { return TimeProxy.Instance.GetRecoverSeconds(item.freeTime); } set { TimeProxy.Instance.CostRecoverKey(item.freeTime); } } public PropBoxInfo(ItemShopBox item) { this.item = item; _unitPrices = Item.ItemInfo.FromArray(item.price, 1); if (item.multiPrice != null && item.multiPrice.Length > 0) { _multiCount = item.multiPrice[0]; _multiPrices = Item.ItemInfo.FromArray(item.multiPrice, 1); } keyPrice = Item.ItemInfo.Convert(item.keyPrice); } /// /// /// /// public bool CheckOpenInterval() { return openInterval <= 0 || openRemainSeconds < 0.001f; } /// /// /// /// public bool CheckOpenFree() { return this.freeInterval > 0 && this.freeRemainSeconds <= 0; } public void Open() { if (openInterval > 0) openRemainSeconds = openInterval; if (freeInterval > 0 && freeRemainSeconds <= 0) freeRemainSeconds = freeInterval; } } /// /// 兑换信息 /// public class ExchangeInfo { public ItemShopBox item; public int id => item.id; public int itemId; public int itemCount; public Item.ItemInfo prop; public Item.ItemInfo price; ObscuredBool _obExchanged; public bool exchanged { get => _obExchanged; set => _obExchanged = value; } public bool useBoxPrice { get { return item.price != null && item.price.Length > 0; } } public ExchangeInfo(ItemShopBox item) { this.item = item; if (item.price != null && item.price.Length > 0) { price = Item.ItemInfo.Convert(item.price, 1); } } public void SetProp(int id, int count) { if (id > 0) { prop.Set(id, count); if (!useBoxPrice) { price = prop.propItem.buyPriceInfo; price.Apply(prop.count); } } else { var chapterBoxes = LevelProxy.Instance.currentChapterItem.shopBox; if (chapterBoxes != null) { var boxInfo = BoxProxy.Instance.GetBoxInfo(chapterBoxes[item.dropBox]); if (boxInfo != null) { prop = boxInfo.GetRndItem(); if (!useBoxPrice) { price = prop.propItem.buyPriceInfo; price.Apply(prop.count); } } } } } } #region Field /// /// /// readonly Dictionary _propBoxInfos = new Dictionary(); /// /// /// readonly Dictionary _exchangeInfos = new Dictionary(); private int _boxId; #endregion #region Property /// /// /// public int exchangeRefreshRemainSecond { get { int result = TimeProxy.Instance.GetRecoverSeconds(4003); if (result <= 0) { result = 0; ResetExchange(); TimeProxy.Instance.CostRecoverKey(4003); } return result; } } #endregion #region Method /// /// 打开那个箱子 /// public int boxId { get { return _boxId; } } /// /// /// /// public int GetRedPoint1() { if (_propBoxInfos.TryGetValue(1, out var boxInfo) && boxInfo.CheckOpenFree()) { return 1; } return 0; } public int GetRedPoint2() { if (_propBoxInfos.TryGetValue(3, out var boxInfo) && boxInfo.CheckOpenFree()) { return 1; } return 0; } public int GetRedPoint3() { if (FunctionProxy.Instance.GetFunctionUnlock(FunctionProxy.FunctionId.红颜养成系统)) if (_propBoxInfos.TryGetValue(4, out var boxInfo) && boxInfo.CheckOpenFree()) { return 1; } return 0; } public int GetRedPoint4() { if (_propBoxInfos.TryGetValue(2, out var boxInfo) && boxInfo.CheckOpenFree()) { return 1; } return 0; } /// /// /// /// /// public PropBoxInfo GetPropBoxInfo(int id) { _propBoxInfos.TryGetValue(id, out var result); return result; } /// /// /// /// public IReadOnlyCollection GetExchangeInfos() { return _exchangeInfos.Values; } /// /// 开道具宝箱 /// /// /// /// public void OpenPropBox(int id, Callback2 callback) { _boxId = id; if (_propBoxInfos.TryGetValue(id, out var boxInfo)) { if (!boxInfo.CheckOpenInterval()) { callback(4, KLocalization.GetLocalString(32)); return; } if (boxInfo.CheckOpenFree()) { OpenPropBoxInternal(boxInfo); callback(ErrorCode.SUCCESS, ErrorMessage.SUCCESS); return; } if (boxInfo.keyPrice.id > 0 && MoneyProxy.Instance.CheckAndCostMoney(boxInfo.keyPrice)) { OpenPropBoxInternal(boxInfo); callback(ErrorCode.SUCCESS, ErrorMessage.SUCCESS); return; } if (boxInfo.adTimeId > 0 && TimeProxy.Instance.CheckTimes(boxInfo.adTimeId)) { AdProxy.Instance.PlayAd("shop", $"ads_prop_box", (error, message) => { if (error == 0) { TimeProxy.Instance.CostTimes(boxInfo.adTimeId); OpenPropBoxInternal(boxInfo); callback(0, ""); } else { callback(error, message); } }); return; } if (boxInfo.unitPrice.id > 0) { if (MoneyProxy.Instance.CheckAndCostMoney(boxInfo.unitPrice)) { OpenPropBoxInternal(boxInfo); callback(0, ""); return; } callback(1, "所需货币不足"); return; } callback(1, ErrorMessage.AD_TIMES_NOT_ENOUGH); } } /// /// 十连道具宝箱 /// /// /// public void OpenPropBox10(int id, Callback2 callback) { _boxId = id; if (_propBoxInfos.TryGetValue(id, out var boxInfo)) { if (MoneyProxy.Instance.CheckAndCostMoney(boxInfo.multiPrice)) { OpenPropBoxMultiInternal(boxInfo); ArchiveProxy.Instance.UploadImmediate(); callback(0, ""); } else { callback(1, "所需货币不足"); } } else { callback(2, "宝箱错误"); } } /// /// /// /// void OpenPropBoxInternal(PropBoxInfo propBoxInfo) { propBoxInfo.Open(); var chapterBoxes = LevelProxy.Instance.currentChapterItem.shopBox; if (chapterBoxes != null) { BoxProxy.BoxInfo rndBoxInfo; if (propBoxInfo.item.random > 0 && RandomProxy.Instance.GetRandom(propBoxInfo.item.random)) { rndBoxInfo = BoxProxy.Instance.GetBoxInfo(chapterBoxes[propBoxInfo.item.randomBox]); } else { rndBoxInfo = BoxProxy.Instance.GetBoxInfo(chapterBoxes[propBoxInfo.item.dropBox]); } if (rndBoxInfo != null) { var rndItem = rndBoxInfo.GetRndItem(); RewardProxy.Instance.GetReward(rndItem); UI.RewardWindow.ShowBox(rndItem, (error, message) => { PostNotification(GlobalDefine.EVENT_MONEY_CHANGED); }); //RewardProxy.Instance.GetRewardWithUI(rndItem, (error, message) => //{ // PostNotification(GlobalDefine.EVENT_MONEY_CHANGED); //}); } } //SaveShop(); } /// /// /// /// void OpenPropBoxMultiInternal(PropBoxInfo propBoxInfo) { var chapterBoxes = LevelProxy.Instance.currentChapterItem.shopBox; if (chapterBoxes != null) { int multi = propBoxInfo.multiCount; var boxInfo = BoxProxy.Instance.GetBoxInfo(chapterBoxes[propBoxInfo.item.dropBox]); var rewards = F.ListPool.Get(); if (propBoxInfo.item.random > 0) { var rndBoxInfo = BoxProxy.Instance.GetBoxInfo(chapterBoxes[propBoxInfo.item.randomBox]); if (rndBoxInfo != null) { rewards.Add(rndBoxInfo.GetRndItem()); multi -= 1; } } if (boxInfo != null) { for (int i = 0; i < multi; i++) { rewards.Add(boxInfo.GetRndItem()); } } var type = rewards[0].propItem.type; //做是否是第一次10连武器宝箱识别 if (type == 3 || type == 4) { var openTenBoxTime = PlayerPrefs.GetInt("TenBoxTime", 0); if (openTenBoxTime == 0) { PlayerPrefs.SetInt("TenBoxTime", 1); } } RewardProxy.Instance.GetRewards(rewards); UI.RewardWindow.ShowBoxs(rewards, (error, message) => { PostNotification(GlobalDefine.EVENT_MONEY_CHANGED); }); F.ListPool.Release(rewards); } } /// /// /// /// /// public void Exchange(int id, Callback2 callback) { if (_exchangeInfos.TryGetValue(id, out var exchangeInfo)) { if (exchangeInfo.exchanged) { callback(1, "今日已兑换"); return; } if (exchangeInfo.price.id == Item.Id.kAds) { AdProxy.Instance.PlayAd("shop", $"ads_exchange", (error, message) => { if (error == 0) { ExchangeInternal(exchangeInfo); callback(0, ""); } else { callback(error, message); } }); } else { if (MoneyProxy.Instance.CheckAndCostMoney(exchangeInfo.price)) { ExchangeInternal(exchangeInfo); callback(0, ""); } else { callback(ErrorCode.MONEY_NOT_ENOUGH, "货币不足"); } } } } void ExchangeInternal(ExchangeInfo exchangeInfo) { exchangeInfo.exchanged = true; SaveShop(); RewardProxy.Instance.GetRewardWithUI(exchangeInfo.prop, (error, message) => { PostNotification(GlobalDefine.EVENT_MONEY_CHANGED); }); } /// /// /// public void ResetExchange() { foreach (var item in _exchangeInfos.Values) { item.exchanged = false; item.SetProp(0, 0); } SaveShop(); //PostNotification(GlobalDefine.EVENT_SHOP_SLOT_CHANGED); } private void InitShop() { _propBoxInfos.Clear(); _exchangeInfos.Clear(); var shopBoxes = ItemProxy.Instance.GetStaticItems(); if (shopBoxes != null) foreach (var shopBox in shopBoxes) { if (shopBox.type == 1) { _propBoxInfos.Add(shopBox.id, new PropBoxInfo(shopBox)); } else if (shopBox.type == 5) { _exchangeInfos.Add(shopBox.id, new ExchangeInfo(shopBox)); } } } const string ARCHIVE_KEY_V1 = "box_shop_v1"; private void LoadShop() { var dataList = ArchiveProxy.Instance.GetIntList(ARCHIVE_KEY_V1); if (dataList != null && dataList.Count > 0) { if (exchangeRefreshRemainSecond <= 0) { ResetExchange(); } else { int index = 0; int count = dataList[index++]; for (int i = 3; i < dataList.Count; i += 3) { int exchangeStatus = dataList[i - 2]; int propId = dataList[i - 1]; int propCount = dataList[i]; int exchangeId = Mathf.Abs(exchangeStatus); if (_exchangeInfos.TryGetValue(exchangeId, out var exchangeInfo)) { exchangeInfo.exchanged = exchangeStatus < 0; exchangeInfo.SetProp(propId, propCount); } } } } else { ResetExchange(); } } private void SaveShop() { var shopList = ArchiveProxy.Instance.GetIntList(ARCHIVE_KEY_V1); if (shopList != null) { shopList.Clear(); shopList.Add(_exchangeInfos.Count); foreach (var item in _exchangeInfos.Values) { shopList.Add(item.exchanged ? -item.id : item.id); shopList.Add(item.prop.id); shopList.Add(item.prop.count); } ArchiveProxy.Instance.SetIntList(ARCHIVE_KEY_V1, shopList); } } #endregion #region Unity & PROXY public override int priority => 19; public static BoxShopProxy Instance; // Use this for initialization private void Awake() { Instance = this; } public override void ReadArchive() { InitShop(); LoadShop(); } #endregion } }