using System;
|
using System.Collections;
|
using System.Collections.Generic;
|
using System.Linq;
|
using UnityEngine;
|
|
public class FirstChargeManager : GameSystemManager<FirstChargeManager>
|
{
|
public const int FuncID = 110;
|
public int mainItemId { get { return GetMainItemId(); } }
|
public int heroItemID;
|
public int maxGiftCount
|
{
|
get
|
{
|
var list = FirstChargeConfig.GetKeys();
|
return list.IsNullOrEmpty() ? 0 : list.Count;
|
}
|
}
|
public int maxDay = 3;
|
public Redpoint parentRedpoint = new Redpoint(MainRedDot.FirstChargeRepoint);
|
|
public Dictionary<int, Redpoint> tabRedpointDict = new Dictionary<int, Redpoint>();
|
public Dictionary<int, bool> clickTabDict = new Dictionary<int, bool>();
|
public Dictionary<int, FirstChargeData> firstChargeInfoDict = new Dictionary<int, FirstChargeData>();
|
public event Action OnUpdateFirstChargeInfo;
|
public override void Init()
|
{
|
DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent += OnBeforePlayerDataInitializeEvent;
|
DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent += OnPlayerLoginOk;
|
RechargeManager.Instance.rechargeCountEvent += OnRechargeCountEvent;
|
FuncOpen.Instance.OnFuncStateChangeEvent += OnFuncStateChangeEvent;
|
|
}
|
|
public override void Release()
|
{
|
DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent -= OnBeforePlayerDataInitializeEvent;
|
DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent -= OnPlayerLoginOk;
|
RechargeManager.Instance.rechargeCountEvent -= OnRechargeCountEvent;
|
FuncOpen.Instance.OnFuncStateChangeEvent -= OnFuncStateChangeEvent;
|
}
|
|
private void OnFuncStateChangeEvent(int obj)
|
{
|
if (FuncID == obj)
|
{
|
string key = $"FirstCharge_FirstTime_{FuncID}_{PlayerDatas.Instance.baseData.PlayerID}";
|
if (!LocalSave.HasKey(key))
|
{
|
// 第一次开启功能
|
LocalSave.SetBool(key, true);
|
PopupWindowsProcessor.Instance.Add("FirstChargeWin");
|
}
|
}
|
}
|
|
public void InitClickTabDict()
|
{
|
var list = FirstChargeConfig.GetKeys();
|
if (!list.IsNullOrEmpty())
|
{
|
for (int i = 0; i < list.Count; i++)
|
{
|
int firstId = list[i];
|
clickTabDict[firstId] = false;
|
}
|
}
|
}
|
public bool GetClickTabState(int fristId)
|
{
|
return clickTabDict.ContainsKey(fristId) && clickTabDict[fristId];
|
}
|
public void SetClickTabState(int fristId)
|
{
|
clickTabDict[fristId] = true;
|
UpdateRedPoint();
|
}
|
|
public void InitRedPoint()
|
{
|
var list = FirstChargeConfig.GetKeys();
|
if (!list.IsNullOrEmpty())
|
{
|
for (int i = 0; i < list.Count; i++)
|
{
|
int firstId = list[i];
|
int redpointId = GetRedpointIdByFirstId(firstId);
|
tabRedpointDict[firstId] = new Redpoint(MainRedDot.FirstChargeRepoint, redpointId);
|
}
|
}
|
|
}
|
|
public int GetRedpointIdByFirstId(int firstId)
|
{
|
return MainRedDot.FirstChargeRepoint * 10000 + firstId;
|
}
|
|
private void OnRechargeCountEvent(int obj)
|
{
|
var list = FirstChargeConfig.GetCtgIDList();
|
if (!list.IsNullOrEmpty() && list.Contains(obj))
|
{
|
UpdateRedPoint();
|
}
|
}
|
|
public void OnBeforePlayerDataInitializeEvent()
|
{
|
firstChargeInfoDict.Clear();
|
}
|
public void OnPlayerLoginOk()
|
{
|
InitClickTabDict();
|
InitRedPoint();
|
if (FuncOpen.Instance.IsFuncOpen(FuncID)&& TryGetUnBuyFirstId(out int firstId))
|
{
|
PopupWindowsProcessor.Instance.Add("FirstChargeWin");
|
}
|
}
|
public bool TryGetFirstChargeDataByFirstId(int firstId, out FirstChargeData firstChargeData)
|
{
|
return firstChargeInfoDict.TryGetValue(firstId, out firstChargeData);
|
}
|
|
public bool TryGetUnBuyFirstId(out int firstId)
|
{
|
firstId = 0;
|
var firstChargeList = FirstChargeConfig.GetKeys();
|
if (firstChargeList != null)
|
{
|
firstChargeList.Sort();
|
foreach (int item in firstChargeList)
|
{
|
if (TryGetFirstChargeDataByFirstId(item, out FirstChargeData data))
|
{
|
if (data.IsUnlock() && !data.IsBuy())
|
{
|
firstId = item;
|
return true;
|
}
|
}
|
|
}
|
}
|
return false;
|
}
|
|
/// <summary>
|
/// 根据标签页索引获取对应的首充ID
|
/// </summary>
|
/// <param name="tabIndex">标签页索引,从0开始</param>
|
/// <returns>对应的首充ID,从1开始</returns>
|
public int GetFirstIDByTabIndex(int tabIndex)
|
{
|
return tabIndex + 1;
|
}
|
|
/// <summary>
|
/// 根据首充ID获取对应的标签页索引
|
/// </summary>
|
/// <param name="firstId">首充ID,从1开始</param>
|
/// <returns>对应的标签页索引,从0开始</returns>
|
public int GetTabIndexByFirstID(int firstId)
|
{
|
return Math.Max(firstId - 1, 0);
|
}
|
|
public int GetLastFirstIDByTabIndex(int tabIndex)
|
{
|
return GetFirstIDByTabIndex(tabIndex == 0 ? tabIndex : tabIndex - 1);
|
}
|
public int GetNextFirstIDByTabIndex(int tabIndex)
|
{
|
return GetFirstIDByTabIndex(tabIndex >= maxGiftCount - 1 ? maxGiftCount - 1 : tabIndex + 1);
|
}
|
public int GetLastFirstIDByFirstID(int firstId)
|
{
|
int tabIndex = GetTabIndexByFirstID(firstId);
|
return GetLastFirstIDByTabIndex(tabIndex);
|
}
|
public int GetNextFirstIDByFirstID(int firstId)
|
{
|
int tabIndex = GetTabIndexByFirstID(firstId);
|
return GetNextFirstIDByTabIndex(tabIndex);
|
}
|
|
public bool TryGetFirstChargeConfigByFirstID(int firstId, out FirstChargeConfig firstChargeConfig)
|
{
|
firstChargeConfig = null;
|
if (!FirstChargeConfig.HasKey(firstId))
|
return false;
|
firstChargeConfig = FirstChargeConfig.Get(firstId);
|
return true;
|
}
|
|
public bool TryGetOrderInfoConfigByFirstID(int firstId, out OrderInfoConfig orderInfoConfig)
|
{
|
orderInfoConfig = null;
|
if (!TryGetFirstChargeConfigByFirstID(firstId, out FirstChargeConfig firstChargeConfig))
|
return false;
|
int ctgId = firstChargeConfig.CTGID;
|
return RechargeManager.Instance.TryGetOrderInfo(ctgId, out orderInfoConfig);
|
}
|
|
public bool TryGetCTGConfigByFirstID(int firstId, out CTGConfig ctgConfig)
|
{
|
ctgConfig = null;
|
if (!TryGetFirstChargeConfigByFirstID(firstId, out FirstChargeConfig firstChargeConfig))
|
return false;
|
int ctgId = firstChargeConfig.CTGID;
|
if (!CTGConfig.HasKey(ctgId))
|
return false;
|
ctgConfig = CTGConfig.Get(ctgId);
|
return true;
|
}
|
public int GetMainItemId()
|
{
|
var list = FirstChargeConfig.GetKeys();
|
list.Sort();
|
var config = FirstChargeConfig.Get(list[0]);
|
for (int i = 0; i < config.AwardListDay1.Length; i++)
|
{
|
int itemId = config.AwardListDay1[i][0];
|
if (!ItemConfig.HasKey(itemId))
|
continue;
|
if (ItemConfig.Get(itemId).Type == 150)
|
{
|
return itemId;
|
}
|
}
|
return 0;
|
}
|
|
public void UpdateFirstChargeInfo(HAA02_tagSCFirstChargeInfo vNetData)
|
{
|
if (vNetData.FirstChargeList.IsNullOrEmpty())
|
return;
|
foreach (var chargeInfo in vNetData.FirstChargeList)
|
{
|
int firstID = chargeInfo.FirstID;
|
if (!firstChargeInfoDict.TryGetValue(firstID, out var firstChargeData))
|
{
|
firstChargeData = new FirstChargeData();
|
firstChargeInfoDict[firstID] = firstChargeData;
|
}
|
firstChargeData.FirstID = firstID;
|
firstChargeData.ChargeTime = chargeInfo.ChargeTime;
|
firstChargeData.AwardRecord = chargeInfo.AwardRecord;
|
}
|
// 检查是否所有奖励都已领取,如果是,则记录当前服务器时间到本地
|
CheckAndSaveAllRewardsClaimedTime();
|
UpdateRedPoint();
|
OnUpdateFirstChargeInfo?.Invoke();
|
}
|
|
/// <summary>
|
/// 检查是否所有首充奖励都已领取,如果是,则将当前服务器时间保存到本地
|
/// </summary>
|
private void CheckAndSaveAllRewardsClaimedTime()
|
{
|
// 检查是否所有奖励都已领取
|
if (IsAllFirstChargeRewardsClaimed())
|
{
|
// 生成一个唯一的键来存储时间
|
string key = $"FirstCharge_AllRewardsClaimed_Time_{PlayerDatas.Instance.baseData.PlayerID}";
|
// 将当前服务器时间保存到本地
|
LocalSave.SetString(key, TimeUtility.ServerNow.Ticks.ToString());
|
}
|
}
|
public void UpdateRedPoint()
|
{
|
// 重置所有红点状态
|
parentRedpoint.state = RedPointState.None;
|
foreach (var redpoint in tabRedpointDict.Values)
|
{
|
redpoint.state = RedPointState.None;
|
}
|
|
var firstChargeList = FirstChargeConfig.GetKeys();
|
if (firstChargeList.IsNullOrEmpty())
|
return;
|
firstChargeList.Sort();
|
foreach (int firstId in firstChargeList)
|
{
|
if (!tabRedpointDict.ContainsKey(firstId))
|
continue;
|
var redpoint = tabRedpointDict[firstId];
|
|
if (TryGetFirstChargeDataByFirstId(firstId, out var firstChargeData))
|
{
|
if (firstChargeData.IsBuy())
|
{
|
for (int day = 1; day <= maxDay; day++)
|
{
|
int awardState = firstChargeData.GetHaveState(day);
|
// 2: 可领取
|
if (awardState == 2)
|
{
|
redpoint.state = RedPointState.Simple;
|
break;
|
}
|
}
|
}
|
else
|
{
|
bool clickTabState = GetClickTabState(firstId);
|
if (firstChargeData.IsUnlock() && !clickTabState)
|
{
|
redpoint.state = RedPointState.Simple;
|
}
|
}
|
}
|
|
|
}
|
}
|
|
/// <summary>
|
/// 发送领取首充奖励请求
|
/// </summary>
|
/// <param name="day">要领取的奖励是第x天的, 从1开始</param>
|
/// <param name="firstID">首充表的ID</param>
|
public void SendGetReward(int day, int firstID)
|
{
|
var pack = new CA504_tagCMPlayerGetReward();
|
pack.RewardType = 8;
|
pack.DataEx = (uint)day;//第x天,1代表第1天
|
string firstIdStr = firstID.ToString();//领取哪个首充ID,对应首充表的ID
|
pack.DataExStr = firstIdStr;
|
pack.DataExStrLen = (byte)firstIdStr.Length;
|
GameNetSystem.Instance.SendInfo(pack);
|
}
|
|
/// <summary>
|
/// 自动领取玩家可以领取的所有首充奖励
|
/// </summary>
|
/// <param name="firstID">首充表的ID</param>
|
public void AutoClaimAllRewards(int firstID)
|
{
|
if (!TryGetFirstChargeDataByFirstId(firstID, out var firstChargeData))
|
return;
|
if (!firstChargeData.IsBuy())
|
return;
|
// 获取当前是购买后的第几天
|
int currentDay = firstChargeData.GetNowBuyDay();
|
// 遍历从第1天到当前天数的所有奖励
|
for (int day = 1; day <= maxDay; day++)
|
{
|
// 检查奖励状态,只有状态为已购买没领取才发送领取请求
|
if (day <= currentDay && firstChargeData.GetHaveState(day) == 2)//0: 已领取 1: 不可领取 2: 可领取
|
{
|
SendGetReward(day, firstID);
|
}
|
}
|
}
|
|
// 检查是否所有首充奖励都已经领取
|
public bool IsAllFirstChargeRewardsClaimed()
|
{
|
// 获取所有首充配置ID
|
var firstChargeIds = FirstChargeConfig.GetKeys();
|
if (firstChargeIds == null || firstChargeIds.Count == 0)
|
return false;
|
|
foreach (var firstId in firstChargeIds)
|
{
|
// 尝试获取首充数据
|
if (!TryGetFirstChargeDataByFirstId(firstId, out var firstChargeData))
|
return false;
|
|
// 检查是否购买
|
if (!firstChargeData.IsBuy())
|
return false;
|
|
// 检查是否所有奖励都已领取
|
if (!firstChargeData.IsAllHave())
|
return false;
|
}
|
|
// 所有首充档位都已购买且所有奖励都已领取
|
// 检查是否已经过了第二天0点
|
return true;
|
}
|
|
// 检查是否已经过了所有奖励领取完毕后的第二天0点
|
public bool IsNextDayAfterAllClaimed()
|
{
|
// 生成一个唯一的键来获取时间
|
string key = $"FirstCharge_AllRewardsClaimed_Time_{PlayerDatas.Instance.baseData.PlayerID}";
|
|
// 检查是否存在记录的时间戳
|
if (!LocalSave.HasKey(key))
|
return false;
|
|
// 获取记录的时间戳
|
string timeString = LocalSave.GetString(key);
|
if (string.IsNullOrEmpty(timeString))
|
return false;
|
|
// 解析时间戳
|
if (!long.TryParse(timeString, out long ticks))
|
return false;
|
|
// 将时间戳转换为DateTime
|
DateTime allRewardsClaimedTime = new DateTime(ticks);
|
|
// 计算第二天0点的时间
|
DateTime nextDayStart = allRewardsClaimedTime.Date.AddDays(1);
|
|
// 判断当前服务器时间是否已经过了第二天0点
|
DateTime serverNow = TimeUtility.ServerNow;
|
return serverNow >= nextDayStart;
|
}
|
|
}
|
public class FirstChargeData
|
{
|
public int FirstID; //首充ID
|
public uint ChargeTime; //充值该首充的时间戳
|
public ushort AwardRecord; //首充奖励领奖记录,按二进制位记录首充第X天是否已领取(第1天对应第1位)
|
|
public bool IsUnlock()
|
{
|
int tabIndex = FirstChargeManager.Instance.GetTabIndexByFirstID(FirstID);
|
if (tabIndex == 0)
|
return true;
|
int lastFirstID = FirstChargeManager.Instance.GetLastFirstIDByTabIndex(tabIndex);
|
FirstChargeData firstChargeDataNow;
|
if (!FirstChargeManager.Instance.TryGetFirstChargeDataByFirstId(lastFirstID, out firstChargeDataNow))
|
return false;
|
return firstChargeDataNow.IsBuy();
|
}
|
|
public bool IsBuy()
|
{
|
return ChargeTime > 0;
|
}
|
|
/// <summary>
|
/// 检查指定天的奖励是否已领取
|
/// </summary>
|
/// <param name="day">天数,从1开始</param>
|
public bool IsHave(int day)
|
{
|
bool res = (AwardRecord & (1 << day)) != 0;
|
return res;
|
}
|
|
public bool IsAllHave()
|
{
|
int maxGiftCount = FirstChargeManager.Instance.maxGiftCount;
|
for (int i = 1; i <= maxGiftCount; i++)
|
{
|
if (!IsHave(i))
|
return false;
|
}
|
return true;
|
}
|
|
// ... existing code ...
|
/// <summary>
|
/// 获取当前时间是购买这档充值礼包的第几天
|
/// 购买的当天算作第一天,第二天0点后算第二天,以此类推
|
/// </summary>
|
/// <returns>第几天</returns>
|
public int GetNowBuyDay()
|
{
|
DateTime serverNow = TimeUtility.ServerNow;
|
DateTime chargeTime = TimeUtility.GetTime(ChargeTime);
|
|
DateTime chargeDate = chargeTime.Date;
|
DateTime serverDate = serverNow.Date;
|
|
// 计算从充值日期到当前日期的完整天数
|
// 购买的当天算第一天,第二天0点后算第二天
|
TimeSpan timeSpan = serverDate - chargeDate;
|
int days = (int)timeSpan.TotalDays + 1; // +1 因为当天算第一天
|
|
int maxDay = FirstChargeManager.Instance.maxDay;
|
|
return Mathf.Min(maxDay, Mathf.Max(1, days));
|
}
|
|
public bool HasNextDay()
|
{
|
int currentDay = GetNowBuyDay();
|
int maxDay = FirstChargeManager.Instance.maxDay;
|
return currentDay < maxDay;
|
}
|
|
/// <summary>
|
/// 获得指定天的领取详细状态
|
/// </summary>
|
/// <param name="day">天数,从1开始</param>
|
//0: 已领取 1: 不可领取 2: 可领取
|
public int GetHaveState(int day)
|
{
|
if (IsHave(day))
|
return 0;
|
int currentDay = GetNowBuyDay();
|
// 检查是否可以领取(购买这档充值礼包的第一天后才可领取)
|
return day <= currentDay ? 2 : 1;
|
}
|
|
/// <summary>
|
/// 返回显示距离第二天0点解锁奖励剩余时间
|
/// </summary>
|
/// <returns>剩余时间字符串,格式:小时:分钟:秒钟</returns>
|
public string GetNextDayUnlockRemainingTime()
|
{
|
if (!IsBuy())
|
return string.Empty;
|
DateTime serverNow = TimeUtility.ServerNow;
|
DateTime nextDayStart = serverNow.Date.AddDays(1);
|
TimeSpan remainingTime = nextDayStart - serverNow;
|
int remainingSeconds = (int)remainingTime.TotalSeconds;
|
return TimeUtility.SecondsToHMS(remainingSeconds);
|
}
|
|
}
|