Files
MinFt/Client/Assets/Scripts/TimeManager/TimeRefreshManager.cs
2026-04-27 12:07:32 +08:00

161 lines
4.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using asap.core;
using game;
using GameCore;
using TimeManager.Event;
using UniRx;
using UnityEngine;
namespace TimeManager
{
/// <summary>
/// 时间刷新管理器 - 检测跨天、跨小时并触发刷新。须在启动链中显式 <c>Resolve&lt;TimeRefreshManager&gt;()</c>(见 ActivityManager.Init
/// </summary>
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
/// <summary>
/// 判断上次登录是否是今天
/// 从 UserService 获取 PlayFab 记录的真实上次登录时间
/// </summary>
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;
}
/// <summary>
/// 判断当前会话是否跨天(从登录到现在的过程中是否跨过了午夜)
/// </summary>
public bool IsSessionCrossDay()
{
var now = ZZTimeHelper.UtcNow().UtcNowOffset();
return _sessionStartTime.DayOfYear != now.DayOfYear ||
_sessionStartTime.Year != now.Year;
}
/// <summary>
/// 判断当前会话是否跨小时(从上次检查到现在是否跨过了整点)
/// </summary>
public bool IsSessionCrossHour()
{
var now = ZZTimeHelper.UtcNow().UtcNowOffset();
return now.Hour != _lastCheckedHour;
}
/// <summary>
/// 获取上次登录时间(从 UserService 获取)
/// </summary>
public DateTime? GetLastLoginTime()
{
return _userService?.LastLoginTime;
}
/// <summary>
/// 获取会话开始时间(本次游戏启动时间)
/// </summary>
public DateTime GetSessionStartTime()
{
return _sessionStartTime;
}
#endregion
/// <summary>
/// 跨天刷新逻辑
/// </summary>
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}");
}
}
/// <summary>
/// 跨小时刷新逻辑
/// </summary>
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.");
}
}
}