2025-05-18 01:04:31 +08:00

670 lines
15 KiB
C#

// ***********************************************************************
// Assembly : Game
// Author : Kimch
// Created : 2020-12-08
// Description :
// Last Modified By :
// Last Modified On :
// ***********************************************************************
// <copyright file= "BoxShopProxy" company="Kunpo"></copyright>
// <summary></summary>
// ***********************************************************************
using CodeStage.AntiCheat.ObscuredTypes;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace G
{
/// <summary>
/// 宝箱商城
/// </summary>
public class BoxShopProxy : F.GameProxy
{
/// <summary>
/// 道具宝箱
/// </summary>
public class PropBoxInfo
{
public readonly ItemShopBox item;
public int id => item.id;
public int type => item.type;
public string name => item.name;
/// <summary>
/// 广告次数Id
/// </summary>
public int adTimeId => item.adTimeId;
private Item.ItemInfo[] _unitPrices;
/// <summary>
/// 单价
/// </summary>
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;
/// <summary>
/// 10次价格
/// </summary>
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;
}
}
/// <summary>
/// 钥匙价格
/// </summary>
public readonly Item.ItemInfo keyPrice;
/// <summary>
/// 开箱间隔
/// </summary>
public int openInterval => item.openInterval;
private int _lastOpenTimestamp;
/// <summary>
/// 开箱(临时保存)
/// </summary>
public int openRemainSeconds
{
get { return Mathf.Max(0, _lastOpenTimestamp - Launch.Timestamp); }
set { _lastOpenTimestamp = Launch.Timestamp + value; }
}
/// <summary>
/// 免费间隔
/// </summary>
public int freeInterval => item.freeTime > 0 ? TimeProxy.Instance.GetRecoverInterval(item.freeTime) : 0;
/// <summary>
///
/// </summary>
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);
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public bool CheckOpenInterval()
{
return openInterval <= 0 || openRemainSeconds < 0.001f;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
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;
}
}
/// <summary>
/// 兑换信息
/// </summary>
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
/// <summary>
///
/// </summary>
readonly Dictionary<int, PropBoxInfo> _propBoxInfos = new Dictionary<int, PropBoxInfo>();
/// <summary>
///
/// </summary>
readonly Dictionary<int, ExchangeInfo> _exchangeInfos = new Dictionary<int, ExchangeInfo>();
private int _boxId;
#endregion
#region Property
/// <summary>
///
/// </summary>
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
/// <summary>
/// 打开那个箱子
/// </summary>
public int boxId
{
get { return _boxId; }
}
/// <summary>
///
/// </summary>
/// <returns></returns>
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;
}
/// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public PropBoxInfo GetPropBoxInfo(int id)
{
_propBoxInfos.TryGetValue(id, out var result);
return result;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public IReadOnlyCollection<ExchangeInfo> GetExchangeInfos()
{
return _exchangeInfos.Values;
}
/// <summary>
/// 开道具宝箱
/// </summary>
/// <param name="id"></param>
/// <param name="callback"></param>
/// <returns></returns>
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);
}
}
/// <summary>
/// 十连道具宝箱
/// </summary>
/// <param name="id"></param>
/// <param name="callback"></param>
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, "宝箱错误");
}
}
/// <summary>
///
/// </summary>
/// <param name="propBoxInfo"></param>
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();
}
/// <summary>
///
/// </summary>
/// <param name="propBoxInfo"></param>
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<Item.ItemInfo>.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<Item.ItemInfo>.Release(rewards);
}
}
/// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <param name="callback"></param>
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);
});
}
/// <summary>
///
/// </summary>
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<ItemShopBox>();
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
}
}