using System; using System.Collections.Generic; using UnityEngine; public class FirstChargeManager : GameSystemManager { public const int FuncID = 21; 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 tabRedpointDict = new Dictionary(); public Dictionary clickTabDict = new Dictionary(); public Dictionary firstChargeInfoDict = new Dictionary(); public event Action OnUpdateFirstChargeInfo; public override void Init() { DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent += OnBeforePlayerDataInitializeEvent; DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent += OnPlayerLoginOk; RechargeManager.Instance.rechargeCountEvent += OnRechargeCountEvent; FuncOpen.Instance.OnFuncStateChangeEvent += OnFuncStateChangeEvent; InitClickTabDict(); InitRedPoint(); } 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() { 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; } /// /// 根据标签页索引获取对应的首充ID /// /// 标签页索引,从0开始 /// 对应的首充ID,从1开始 public int GetFirstIDByTabIndex(int tabIndex) { return tabIndex + 1; } /// /// 根据首充ID获取对应的标签页索引 /// /// 首充ID,从1开始 /// 对应的标签页索引,从0开始 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(); } /// /// 检查是否所有首充奖励都已领取,如果是,则将当前服务器时间保存到本地 /// 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; } } } } } /// /// 发送领取首充奖励请求 /// /// 要领取的奖励是第x天的, 从1开始 /// 首充表的ID 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); } /// /// 自动领取玩家可以领取的所有首充奖励 /// /// 首充表的ID 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; } /// /// 检查指定天的奖励是否已领取 /// /// 天数,从1开始 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 ... /// /// 获取当前时间是购买这档充值礼包的第几天 /// 购买的当天算作第一天,第二天0点后算第二天,以此类推 /// /// 第几天 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; } /// /// 获得指定天的领取详细状态 /// /// 天数,从1开始 //0: 已领取 1: 不可领取 2: 可领取 public int GetHaveState(int day) { if (IsHave(day)) return 0; int currentDay = GetNowBuyDay(); // 检查是否可以领取(购买这档充值礼包的第一天后才可领取) return day <= currentDay ? 2 : 1; } /// /// 返回显示距离第二天0点解锁奖励剩余时间 /// /// 剩余时间字符串,格式:小时:分钟:秒钟 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); } }