using System;
using asap.core;
using game;
using GameCore;
using TimeManager.Event;
using UniRx;
using UnityEngine;
namespace TimeManager
{
///
/// 时间刷新管理器 - 检测跨天、跨小时并触发刷新。须在启动链中显式 Resolve<TimeRefreshManager>()(见 ActivityManager.Init)。
///
public class TimeRefreshManager : IDisposable
{
public TimeRefreshManager(ITimeTickService tickService, IUserService userService)
{
_tickService = tickService;
_userService = userService;
_sessionStartTime = ZZTimeHelper.UtcNow().UtcNowOffset();
_lastCheckedHour = _sessionStartTime.Hour;
CheckLastLogin();
_tickService.MinuteTick
.Subscribe(_ =>
{
CheckSessionCrossDay();
CheckSessionCrossHour();
})
.AddTo(_disposables);
}
private readonly ITimeTickService _tickService;
private readonly IUserService _userService;
private int _lastCheckedDayOfYear = -1;
private int _lastCheckedHour = -1;
private DateTime _sessionStartTime;
private CompositeDisposable _disposables = new();
#region Check登录时间
private void CheckLastLogin()
{
if (IsLastLoginToday()) return;
Debug.Log("上次登录不是今天");
OnCrossDayRefresh();
}
private void CheckSessionCrossDay()
{
if (!IsSessionCrossDay()) return;
OnCrossDayRefresh();
_sessionStartTime = ZZTimeHelper.UtcNow().UtcNowOffset();
}
private void CheckSessionCrossHour()
{
if (!IsSessionCrossHour()) return;
OnCrossHourRefresh();
var now = ZZTimeHelper.UtcNow().UtcNowOffset();
_lastCheckedHour = now.Hour;
}
#endregion
#region 登录时间相关
///
/// 判断上次登录是否是今天
/// 从 UserService 获取 PlayFab 记录的真实上次登录时间
///
public bool IsLastLoginToday()
{
var lastLoginTime = GetLastLoginTime();
if (!lastLoginTime.HasValue)
{
return false; // 从未登录过
}
var now = ZZTimeHelper.UtcNow().UtcNowOffset();
return lastLoginTime.Value.DayOfYear == now.DayOfYear &&
lastLoginTime.Value.Year == now.Year;
}
///
/// 判断当前会话是否跨天(从登录到现在的过程中是否跨过了午夜)
///
public bool IsSessionCrossDay()
{
var now = ZZTimeHelper.UtcNow().UtcNowOffset();
return _sessionStartTime.DayOfYear != now.DayOfYear ||
_sessionStartTime.Year != now.Year;
}
///
/// 判断当前会话是否跨小时(从上次检查到现在是否跨过了整点)
///
public bool IsSessionCrossHour()
{
var now = ZZTimeHelper.UtcNow().UtcNowOffset();
return now.Hour != _lastCheckedHour;
}
///
/// 获取上次登录时间(从 UserService 获取)
///
public DateTime? GetLastLoginTime()
{
return _userService?.LastLoginTime;
}
///
/// 获取会话开始时间(本次游戏启动时间)
///
public DateTime GetSessionStartTime()
{
return _sessionStartTime;
}
#endregion
///
/// 跨天刷新逻辑
///
private void OnCrossDayRefresh()
{
try
{
// 1. 发送活动跨天刷新事件
GContext.Publish(new ActivityCrossDayRefreshEvent());
}
catch (Exception e)
{
Debug.LogError($"[TimeRefreshManager] Error during cross day refresh: {e.Message}\n{e.StackTrace}");
}
}
///
/// 跨小时刷新逻辑
///
private void OnCrossHourRefresh()
{
try
{
// 发送跨小时刷新事件
GContext.Publish(new ActivityCrossHourRefreshEvent());
}
catch (Exception e)
{
Debug.LogError($"[TimeRefreshManager] Error during cross hour refresh: {e.Message}\n{e.StackTrace}");
}
}
public void Dispose()
{
_disposables?.Dispose();
_disposables = null;
Debug.Log("[TimeRefreshManager] Disposed.");
}
}
}