NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Gameplay/Utils/CrossDayChecker.cs

211 lines
6.5 KiB
C#
Raw Normal View History

2024-12-12 17:43:29 +08:00
using System;
using PhxhSDK;
using Framework;
2025-04-09 17:45:53 +08:00
using Gameplay;
2024-12-16 14:10:40 +08:00
using UnityEngine;
2025-04-09 17:45:53 +08:00
using Gameplay.Common;
2024-12-12 17:43:29 +08:00
public class CrossDayChecker : Singlenton<CrossDayChecker>, IUpdatable, IInitable
{
2024-12-16 17:19:05 +08:00
public bool DeleteSaveData;
2024-12-12 17:43:29 +08:00
// 检查时间点
2025-04-09 17:45:53 +08:00
private TimeSpan checkPointTime;
2024-12-12 17:43:29 +08:00
// 记录上次检查的时间
private DateTime lastCheckTime;
2025-04-09 18:33:21 +08:00
// 服务器时间与本地时间的差值(毫秒)
private long serverTimeOffset;
2024-12-16 14:10:40 +08:00
private bool _init;
2025-03-18 12:59:43 +08:00
public bool disableCheck = false;
2024-12-16 14:10:40 +08:00
2024-12-13 17:36:35 +08:00
public void SetCheckTime(TimeSpan checkTime)
{
checkPointTime = checkTime;
}
2024-12-12 17:43:29 +08:00
public void Update(float deltaTime)
{
2024-12-16 14:10:40 +08:00
if (!_init) return;
2025-03-18 12:59:43 +08:00
if (disableCheck) return;
2025-04-09 18:33:21 +08:00
// 使用本地时间加上差值计算服务器时间,避免频繁网络请求
var now = GetEstimatedServerTime();
2024-12-12 17:43:29 +08:00
// 检测跨天
if (HasCrossedDay(lastCheckTime, now))
{
DebugUtil.Log("跨天了!");
EventManager.Instance.Send(EventManager.EventName.CrossDay);
}
// 检测跨周
if (HasCrossedWeek(lastCheckTime, now))
{
DebugUtil.Log("跨周了!");
EventManager.Instance.Send(EventManager.EventName.CrossWeek);
}
// 检测跨月
if (HasCrossedMonth(lastCheckTime, now))
{
DebugUtil.Log("跨月了!");
EventManager.Instance.Send(EventManager.EventName.CrossMonth);
}
lastCheckTime = now;
}
2024-12-16 14:10:40 +08:00
public void InitForLoginOk()
2024-12-12 17:43:29 +08:00
{
2025-04-09 18:33:21 +08:00
// 从配置中获取跨天时间点
2025-04-09 17:45:53 +08:00
checkPointTime = new TimeSpan(GLConfig.Inst.data.DailyChangeHour, 0, 0);
2025-04-09 18:33:21 +08:00
// 初始化时计算服务器时间与本地时间的差值
DateTime serverTime = CommonUtils.GetCurTime(CommonUtils.E_TimeType.Server);
DateTime localTime = DateTime.Now;
serverTimeOffset = (long)(serverTime - localTime).TotalMilliseconds;
DebugUtil.Log($"CrossDayChecker: 服务器时间偏移量:{serverTimeOffset}毫秒");
2024-12-16 14:10:40 +08:00
if (PlayerPrefs.HasKey("CrossDayChecker_LastCheckTime"))
{
string savedTime = PlayerPrefs.GetString("CrossDayChecker_LastCheckTime");
if (DateTime.TryParse(savedTime, out var parsedTime))
{
lastCheckTime = parsedTime;
DebugUtil.Log($"CrossDayChecker: 成功加载上次检查时间:{lastCheckTime}");
}
else
{
2025-04-09 17:45:53 +08:00
DebugUtil.Log("CrossDayChecker: 无法解析存储的时间,使用当前服务器时间作为初始化时间。");
2025-04-09 18:33:21 +08:00
lastCheckTime = serverTime;
2024-12-16 17:19:05 +08:00
SendAllCrossEvent();
2024-12-16 14:10:40 +08:00
}
}
else
{
2025-04-09 17:45:53 +08:00
DebugUtil.Log("CrossDayChecker: 本地存储中未找到上次检查时间,使用当前服务器时间作为初始化时间。");
2025-04-09 18:33:21 +08:00
lastCheckTime = serverTime;
2024-12-16 17:19:05 +08:00
SendAllCrossEvent();
2024-12-16 14:10:40 +08:00
}
2024-12-12 17:43:29 +08:00
2024-12-16 14:10:40 +08:00
_init = true;
2024-12-12 17:43:29 +08:00
}
2025-04-09 18:33:21 +08:00
/// <summary>
/// 根据本地时间和时间偏移量估算服务器时间
/// </summary>
private DateTime GetEstimatedServerTime()
{
return DateTime.Now.AddMilliseconds(serverTimeOffset);
}
2024-12-12 17:43:29 +08:00
/// <summary>
/// 检测是否跨天
/// </summary>
private bool HasCrossedDay(DateTime previousTime, DateTime currentTime)
{
var currentCrossTime = GetCrossTime(currentTime);
return currentTime >= currentCrossTime && previousTime < currentCrossTime;
}
2024-12-13 17:36:35 +08:00
2024-12-12 17:43:29 +08:00
/// <summary>
/// 检测是否跨周
/// </summary>
private bool HasCrossedWeek(DateTime previousTime, DateTime currentTime)
{
var previousCrossTime = GetCrossTime(previousTime).StartOfWeek();
var currentCrossTime = GetCrossTime(currentTime).StartOfWeek();
return currentCrossTime > previousCrossTime && currentTime >= currentCrossTime;
}
/// <summary>
/// 检测是否跨月
/// </summary>
private bool HasCrossedMonth(DateTime previousTime, DateTime currentTime)
{
var previousCrossTime = GetCrossTime(previousTime).StartOfMonth();
var currentCrossTime = GetCrossTime(currentTime).StartOfMonth();
return currentCrossTime > previousCrossTime && currentTime >= currentCrossTime;
}
/// <summary>
/// 获取指定时间的检查点时间
/// </summary>
private DateTime GetCrossTime(DateTime date)
{
2024-12-16 16:36:25 +08:00
// 验证 date 是否在有效范围内
if (date < DateTime.MinValue || date > DateTime.MaxValue)
{
throw new ArgumentOutOfRangeException(nameof(date), "Input date is out of valid range.");
}
2024-12-13 17:36:35 +08:00
var crossTime = date.Date + checkPointTime;
2024-12-16 16:36:25 +08:00
2024-12-13 17:36:35 +08:00
if (date.TimeOfDay < checkPointTime)
2024-12-12 17:43:29 +08:00
{
2024-12-16 16:36:25 +08:00
if (crossTime > DateTime.MinValue.AddDays(1))
{
crossTime = crossTime.AddDays(-1);
}
else
{
crossTime = DateTime.MinValue;
}
2024-12-12 17:43:29 +08:00
}
return crossTime;
}
2024-12-16 14:10:40 +08:00
2024-12-16 17:19:05 +08:00
private void SendAllCrossEvent()
{
EventManager.Instance.Send(EventManager.EventName.CrossDay);
EventManager.Instance.Send(EventManager.EventName.CrossWeek);
EventManager.Instance.Send(EventManager.EventName.CrossMonth);
}
2024-12-16 14:10:40 +08:00
public void Init()
{
}
public void Release()
{
2024-12-16 17:19:05 +08:00
if (DeleteSaveData) return;
2024-12-16 14:10:40 +08:00
PlayerPrefs.SetString("CrossDayChecker_LastCheckTime", lastCheckTime.ToString("o"));
PlayerPrefs.Save();
DebugUtil.Log($"CrossDayChecker: 保存最后检查时间:{lastCheckTime}");
}
2024-12-12 17:43:29 +08:00
}
/// <summary>
/// DateTime 的扩展方法
/// </summary>
public static class DateTimeExtensions
{
/// <summary>
/// 获取指定日期所在周的起始时间(以跨天时间点为准)
/// </summary>
public static DateTime StartOfWeek(this DateTime date)
{
// 周一为一周的起始
var diff = (int)date.DayOfWeek - (int)DayOfWeek.Monday;
if (diff < 0)
{
diff += 7;
}
return date.AddDays(-diff).Date;
}
/// <summary>
/// 获取指定日期所在月的起始时间(以跨天时间点为准)
/// </summary>
public static DateTime StartOfMonth(this DateTime date)
{
return new DateTime(date.Year, date.Month, 1);
}
}