Files
MinFt/Client/Assets/Scripts/Services/InGameMail.cs
Liubing\LB 3d8d4d18f3 first commit
先修复一下,错误的场景

删除不必要的钓场资产

修复into场景

update:更新meta文件,修复报错

update:修复资源

修复第一章节建造

修复建造第三章

update:删除多余内容

update:更新README.md

update:还原图标

update:更新README

update:更新配置
2026-04-28 02:17:22 +08:00

417 lines
11 KiB
C#
Raw Permalink 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 System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using GameCore;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.Assertions;
/// <summary>
/// 邮件类型枚举
/// </summary>
public enum EMailType
{
Global,
Personal,
AutoDelivery,
}
/// <summary>
/// 邮件状态标志枚举
/// </summary>
[Flags]
public enum EMailState
{
None = 1 << 0, // 通知未读
HasRead = 1 << 1, // 已读通知
RewardTaken = 1 << 2, // 奖励已领取,表示用户已经领取了通知中的奖励
HasDeleted = 1 << 3, // 通知已删除
}
/// <summary>
/// 游戏内邮件服务接口
/// </summary>
public interface IInGameMailService
{
/// <summary>
/// 是否解锁邮件功能。
/// </summary>
bool IsUnlock { get; set; }
/// <summary>
/// 初始化邮件服务。
/// </summary>
void Init();
/// <summary>
/// 重置邮件服务。
/// </summary>
void Reset();
/// <summary>
/// 异步获取新邮件。
/// </summary>
/// <returns>一个任务,表示邮件获取操作。</returns>
Task FetchMail();
/// <summary>
/// 异步获取所有游戏邮件。
/// </summary>
/// <returns>一个任务,包含一个列表,列表中包含所有游戏邮件。</returns>
IList<GameMail> GetAllMail();
/// <summary>
/// 异步标记指定邮件为已读。
/// </summary>
/// <param name="mail">要标记为已读的邮件。</param>
/// <returns>一个任务,表示邮件标记操作是否成功。</returns>
Task<bool> MarkRead(GameMail mail);
/// <summary>
/// 异步标记指定邮件为已读。
/// </summary>
/// <param name="mails">要标记为已读的邮件。null 标记搜有已读</param>
/// <returns>一个任务,表示邮件标记操作是否成功。</returns>
Task<bool> MarkRead(GameMail[] mails = null);
/// <summary>
/// 异步删除指定邮件。
/// </summary>
/// <param name="mail">要删除的邮件。</param>
/// <returns>一个任务,表示邮件删除操作是否成功。</returns>
Task<bool> DelMail(GameMail mail);
/// <summary>
/// 异步删除指定邮件。
/// </summary>
/// <param name="mails">要删除的邮件。null 删除所有已读邮件</param>
/// <returns>一个任务,表示邮件删除操作是否成功。</returns>
Task<bool> DelMail(GameMail[] mails = null);
/// <summary>
/// 异步领取指定邮件的奖励。
/// </summary>
/// <param name="mail">要领取奖励的邮件。</param>
/// <returns>一个任务,表示奖励领取操作是否成功。</returns>
Task<bool> TakeReward(GameMail mail);
/// <summary>
/// 异步领取指定邮件的奖励。
/// </summary>
/// <param name="mails">要领取奖励的邮件。领取所有奖励</param>
/// <returns>一个任务,表示奖励领取操作是否成功。</returns>
Task<bool> TakeReward(GameMail[] mails = null);
}
/// <summary>
/// 邮件缓存类
/// </summary>
public class MailCache
{
private Dictionary<string,GameMail> _dicMails;
private Dictionary<string,cfg.AutoDeliveryMail> _autoDeliveryMail;
private string _mail_key;
private string _sync_time_key;
private string _userId;
public MailCache(cfg.TbAutoDeliveryMail tbAutoDeliveryMail)
{
_autoDeliveryMail = tbAutoDeliveryMail.DataMap
.ToDictionary(e => e.Key.ToString(), v => v.Value);
}
/// <summary>
/// 加载指定用户的邮件缓存
/// </summary>
/// <param name="userId">用户ID</param>
public void Load(string userId)
{
if (userId != this._userId)
{
Debug.Log($"load mail cache for user: {userId}");
this._userId = userId;
_mail_key = $"mail_cache__{userId}";
_sync_time_key = $"mail_sync_Time_{userId}";
var jdata = PlayerPrefs.GetString(_mail_key, string.Empty);
_dicMails = string.IsNullOrEmpty(jdata) ?
new Dictionary<string, GameMail>()
: JsonConvert.DeserializeObject<Dictionary<string, GameMail>>(jdata);
}
}
public void Unload()
{
this._userId = null;
_mail_key = null;
_sync_time_key = null;
_dicMails = null;
}
public DateTime? LastSyncTime
{
get
{
#if UNITY_EDITOR
Assert.IsNotNull(_userId);
#endif
return PlayerPrefs.HasKey(_sync_time_key) ?
DateTime.Parse(PlayerPrefs.GetString(_sync_time_key)) : null;
}
}
/// <summary>
/// 对邮件列表进行排序
/// </summary>
/// <param name="mails">邮件列表</param>
private void SortMails(List<GameMail> mails)
{
//by send time Desc
mails.Sort((a, b) => b.SendTime.CompareTo(a.SendTime));
}
/// <summary>
/// 保存邮件缓存到持久化存储
/// </summary>
public void Save()
{
#if UNITY_EDITOR
Assert.IsNotNull(_userId);
#endif
var jdata = JsonConvert.SerializeObject(_dicMails);
PlayerPrefs.SetString(_mail_key, jdata);
PlayerPrefs.SetString(_sync_time_key, ZZTimeHelper.UtcNow().ToString());
PlayerPrefs.Save();
}
public void UpdateSyncTime()
{
PlayerPrefs.SetString(_sync_time_key, ZZTimeHelper.UtcNow().ToString());
PlayerPrefs.Save();
}
/// <summary>
/// 缓存单封邮件
/// </summary>
/// <param name="mail">邮件对象</param>
public void Cache(GameMail mail)
{
#if UNITY_EDITOR
Assert.IsNotNull(_userId);
#endif
if(_dicMails.ContainsKey(mail.Id))
{
_dicMails[mail.Id].Copy(mail);
}
else
{
FillMail(mail);
_dicMails.Add(mail.Id, mail);
}
}
private void FillMail(GameMail mail)
{
if (mail.Type == EMailType.AutoDelivery)
{
var mailData = _autoDeliveryMail[mail.Id];
mail.Title = LocalizationMgr.GetText(mailData.Title_l10n_key);
mail.Content = LocalizationMgr.GetText(mailData.Content_l10n_key);
mail.From = LocalizationMgr.GetText(mailData.Inscribe_l10n_key);
}
}
/// <summary>
/// 缓存多封邮件
/// </summary>
/// <param name="mails">邮件集合</param>
public void Cache(IEnumerable<GameMail> mails)
{
#if UNITY_EDITOR
Assert.IsNotNull(_userId);
#endif
foreach (var mail in mails)
{
Cache(mail);
}
}
public GameMail GetMail(string id)
{
#if UNITY_EDITOR
Assert.IsNotNull(_userId);
#endif
if (_dicMails.TryGetValue(id, out var mail))
{
return mail;
}
return null;
}
public bool HasMail(string id)
{
#if UNITY_EDITOR
Assert.IsNotNull(_userId);
#endif
return _dicMails.ContainsKey(id);
}
/// <summary>
/// 获取所有未过期且未删除的邮件
/// </summary>
/// <returns>邮件列表</returns>
public IList<GameMail> GetAll()
{
#if UNITY_EDITOR
Assert.IsNotNull(_userId);
#endif
var now = ZZTimeHelper.UtcNow();
var mails = _dicMails.Values
.Where(m => m.ExpireTime > now && !m.IsDeleted)
.ToList();
SortMails(mails);
return mails;
}
public int UnreadMailCount
{
get{
#if UNITY_EDITOR
Assert.IsNotNull(_userId);
#endif
var utcNow = ZZTimeHelper.UtcNow();
return _dicMails.Values.Count(m =>
m.ExpireTime > utcNow
&& !m.IsDeleted
&& (!m.IsRead || !m.HasReward));
}
}
public string PrintCacheMails()
{
return JsonConvert.SerializeObject(_dicMails,Formatting.Indented);
}
}
/// <summary>
/// 邮件处理器接口
/// </summary>
public interface IMailHandler
{
/// <summary>
/// 获取游戏邮件列表
/// </summary>
/// <returns>游戏邮件列表的枚举</returns>
Task<bool> FetchMail();
/// <summary>
/// 发送邮件
/// </summary>
/// <returns>发送是否成功</returns>
Task<bool> SendMail(MailInfo[] mailInfos);
/// <summary>
/// 将指定邮件标记为已读
/// </summary>
/// <param name="mail">邮件</param>
/// <returns>标记是否成功</returns>
Task<bool> MarkAsRead(GameMail mail);
/// <summary>
/// 将多个指定邮件标记为已读
/// </summary>
/// <param name="mails">邮件数组, null 标记所有为已读</param>
/// <returns>标记是否成功</returns>
Task<bool> MarkAsRead(GameMail[] mails = null);
/// <summary>
/// 领取指定邮件的奖励
/// </summary>
/// <param name="mail">邮件</param>
/// <returns>领取是否成功</returns>
Task<bool> TakeReward(GameMail mail);
/// <summary>
/// 领取多个指定邮件的奖励
/// </summary>
/// <param name="mails">邮件数组, null 领取所有奖励</param>
/// <returns>领取是否成功</returns>
Task<bool> TakeReward(GameMail[] mails= null);
/// <summary>
/// 删除指定邮件
/// </summary>
/// <param name="mail">邮件</param>
/// <returns>删除是否成功</returns>
Task<bool> DeleteMail(GameMail mail);
/// <summary>
/// 删除多个指定邮件
/// </summary>
/// <param name="mails">邮件数组, null 删除所有 已读邮件</param>
/// <returns>删除是否成功</returns>
Task<bool> DeleteMail(GameMail[] mails = null);
}
/// <summary>
/// 游戏邮件类
/// </summary>
public class GameMail
{
// 邮件ID用于唯一标识一封邮件
public string Id { get; set; }
// 邮件类型,表示邮件的性质或用途
public EMailType Type { get; set; }
// 邮件发送时间,记录邮件发送的时刻
public DateTime SendTime { get; set; }
// 邮件过期时间,表示邮件有效的截止时间
public DateTime ExpireTime { get; set; }
// 邮件状态,表示邮件当前的各种状态(如是否已读、是否删除等)
public EMailState State { get; set; }
// 邮件标题,简短概括邮件内容的主题
public string Title { get; set; }
// 邮件发送方,记录邮件发送方
public string From { get; set; }
// 邮件内容,详细描述邮件的信息
public string Content { get; set; }
// 邮件附带的物品ID数组表示邮件可能附带的物品或奖励
public int[] DropIds { get; set; }
// 判断邮件是否含有附带物品
public bool HasDrops => DropIds != null && DropIds.Length > 0;
// 判断邮件是否含有奖励如果含有附带物品且奖励未被领取则返回true
public bool HasReward => !HasDrops || (State & EMailState.RewardTaken) == EMailState.RewardTaken;
// 判断邮件是否已被阅读
public bool IsRead => (State & EMailState.HasRead) == EMailState.HasRead;
// 判断邮件是否已被删除
public bool IsDeleted => (State & EMailState.HasDeleted) == EMailState.HasDeleted;
public void Copy(GameMail mail)
{
Id = mail.Id;
Type = mail.Type;
SendTime = mail.SendTime;
ExpireTime = mail.ExpireTime;
State = mail.State;
Title = mail.Title;
From = mail.From;
Content = mail.Content;
DropIds = mail.DropIds;
}
}