using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using asap.core; using game; using GameCore; using Newtonsoft.Json; using UniRx; public class FetchMailRequest { public DateTime? lastSyncTime; } public class FetchMailResp { public bool success; public List mails; public string error; } public class MailStateInfo { public string Id { get; set; } public EMailState state { get; set; } public MailStateInfo(GameMail mail, EMailState newState) { Id = mail.Id.ToString(); state = mail.State | newState; } } public class UpdateMailStateRequest { public MailStateInfo[] mailStates; } public class UpdateMailStateResp { public bool success; public MailStateInfo[] states; } public class FetchMailEvt { DateTime TimeStamp; } public class MailInfo { public string Id { get; set; } public EMailType Type { get; set; } public int expireDays { get; set; } public string Title { get; set; } public string From { get; set; } public string Content { get; set; } public int[] DropIds { get; set; } } public class SendMailRequest { public MailInfo[] mailInfos; } public class SendMailResp { public bool success; public List mails; public string error; } public class AutoMailData { public string Id; public int levelMin; public int levelMax; public DateTime accountCreateTime; public DateTime loginTimeMin; public DateTime loginTimeMax; public int expireDays; public int DropID; public AutoMailData(cfg.AutoDeliveryMail mail) { Id = mail.MailID.ToString(); levelMin = mail.AccountLevelRange[0]; levelMax = mail.AccountLevelRange[1] == -1 ? int.MaxValue : mail.AccountLevelRange[1]; accountCreateTime = DateTime.Parse(mail.AccountCreateTimestamp); loginTimeMin = DateTime.Parse(mail.LoginTimestampRange[0]); loginTimeMax = DateTime.Parse(mail.LoginTimestampRange[1]); DropID = mail.DropID; expireDays = mail.ExpireDay; } public bool IsSatisfy(DateTime loginTime, DateTime CreateTime, int level) { return loginTime >= loginTimeMin && loginTime <= loginTimeMax && CreateTime < accountCreateTime && level >= levelMin && level <= levelMax; } public MailInfo ToMailInfo() { return new MailInfo { Id = Id.ToString(), Type = EMailType.AutoDelivery, DropIds = new[] { DropID }, expireDays = expireDays }; } } public static class MailUrls { public const string Fetch = "mail/fetch"; public const string UpdateState = "mail/updateState"; public const string Send = "mail/send"; } public class InGameMailService : IInGameMailService { private MailCache _mailCache; private IMailHandler _handler; private List _autoMailDatas; private CompositeDisposable _disposables; private bool _forceFetch = false; //private const int Fetch_Interval = 3; public bool IsUnlock { get; set; } public InGameMailService(cfg.Tables tables) { this._mailCache = new MailCache(tables.TbAutoDeliveryMail); this._handler = new BaseMailHandler(_mailCache); _autoMailDatas = tables.TbAutoDeliveryMail.DataList .Select(x => new AutoMailData(x)).ToList(); } public void Init() { var userService = GContext.container.Resolve(); _mailCache.Load(userService.UserId); _disposables = new CompositeDisposable(); var minActiveLevel = _autoMailDatas.Min(x => x.levelMin) - 1; if (userService.IsAuthorized) _handler.FetchMail(); else GContext.OnEvent().Subscribe(_ => _handler.FetchMail()).AddTo(_disposables); GContext.OnEvent() .Skip(1) .Where(x => x.lvl >= minActiveLevel) .Subscribe(OnLevelChange) .AddTo(_disposables); //GContext.OnEvent() //.Skip(1) //.Subscribe(OnHomeUIShow) //.AddTo(_disposables); } public void Reset() { _mailCache?.Unload(); _disposables?.Dispose(); _disposables = null; } public async Task FetchMail() { await _handler.FetchMail(); } public IList GetAllMail() { return _mailCache.GetAll(); } public async Task MarkRead(GameMail mail) { return await _handler.MarkAsRead(mail); } public async Task MarkRead(GameMail[] mails = null) { return await _handler.MarkAsRead(mails); } public async Task DelMail(GameMail mail) { return await _handler.DeleteMail(mail); } public async Task DelMail(GameMail[] mails = null) { return await _handler.DeleteMail(mails); } public async Task TakeReward(GameMail mail) { return await _handler.TakeReward(mail); } public async Task TakeReward(GameMail[] mails) { return await _handler.TakeReward(mails); } private void OnLevelChange(OnLvChangeEvent evt) { #if UNITY_EDITOR UnityEngine.Debug.Log("[InGameMailService] OnLevelChange"); #endif GenAutoDeliveryMail(); } //private async void OnHomeUIShow(RestartShowHomeUIEvent evt) //{ //#if UNITY_EDITOR //var deltaTime = _mailCache.LastSyncTime == null ? 0 : (ZZTimeHelper.UtcNow() - _mailCache.LastSyncTime.Value).TotalSeconds; //UnityEngine.Debug.Log($"[InGameMailService] OnHomeUIShow deltaTime {deltaTime}"); //#endif //if(_mailCache.LastSyncTime == null //|| _forceFetch //|| ZZTimeHelper.UtcNow() - _mailCache.LastSyncTime.Value > TimeSpan.FromMinutes(Fetch_Interval)) //{ //if(await _handler.FetchMail()) //{ //_forceFetch = false; //} //} //} private async void GenAutoDeliveryMail() { var playerData = GContext.container.Resolve(); var userData = GContext.container.Resolve(); var mailsToSend = _autoMailDatas.Where(m => !_mailCache.HasMail(m.Id) && m.IsSatisfy(userData.LoginTime, userData.CreateTime, playerData.lv)) .Select(m => m.ToMailInfo()) .ToArray(); if (mailsToSend.Length > 0) { if (await _handler.SendMail(mailsToSend)) { _forceFetch = true; } } #if UNITY_EDITOR var mailids = mailsToSend.Select(m => m.Id); var mailidsStr = string.Join(',', mailids); UnityEngine.Debug.Log($"[InGameMailService] GenAutoDeliveryMail {mailidsStr}"); #endif } public void PrintCacheMail() { UnityEngine.Debug.Log(_mailCache.PrintCacheMails()); } } public class BaseMailHandler : IMailHandler { protected MailCache _cache; public BaseMailHandler(MailCache cache) { this._cache = cache; } public virtual async Task FetchMail() { try { await Awaiters.NextFrame; #if UNITY_EDITOR UnityEngine.Debug.Log($"[InGameMailService] Start Fetch Mails"); #endif var req = new FetchMailRequest() { lastSyncTime = _cache.LastSyncTime }; // [REMOVED] CustomServerMgr deleted return false; } catch (Exception e) { UnityEngine.Debug.LogException(e); } UnityEngine.Debug.LogWarning("[InGameMailService] FetchMail Failed"); return false; } public async Task SendMail(MailInfo[] mailInfos) { try { var req = new SendMailRequest() { mailInfos = mailInfos }; // [REMOVED] CustomServerMgr deleted return false; } catch (Exception e) { UnityEngine.Debug.LogError(e); } return false; } protected virtual async Task UpdateMailState(GameMail[] mails, EMailState state) { var req = new UpdateMailStateRequest() { mailStates = mails.Select(m => new MailStateInfo(m, state)).ToArray() }; // [REMOVED] CustomServerMgr deleted return false; } public virtual async Task MarkAsRead(GameMail mail) { if (mail.IsRead) return false; var result = await UpdateMailState(new[] { mail }, EMailState.HasRead); if (result) _cache.Save(); return result; } public virtual async Task MarkAsRead(GameMail[] mails = null) { if (mails == null) { mails = _cache.GetAll() .Where(m => !m.IsRead) .ToArray(); } return await UpdateMailState(mails, EMailState.HasRead); } public async Task TakeReward(GameMail mail) { if (!mail.HasDrops || mail.HasReward) return false; var result = await UpdateMailState(new[] { mail }, EMailState.RewardTaken); if (result) { _cache.Save(); if (mail.Type == EMailType.Personal) { GContext.container.Resolve().AddItemByDropListLureInflation(null, mail.DropIds.ToList(), null); } else { GContext.container.Resolve().AddItemByDropList(mail.DropIds.ToList(), null); } GContext.Publish(new ShowData()); } return result; } public async Task TakeReward(GameMail[] mails = null) { if (mails == null) { mails = _cache.GetAll() .Where(m => m.HasDrops && !m.HasReward) .ToArray(); } else { mails = mails.Where(m => m.HasDrops && !m.HasReward) .ToArray(); } if (mails.Length == 0) return false; var result = await UpdateMailState(mails, EMailState.HasRead); if (result) { _cache.Save(); var drops = mails.Where(m => m.HasReward) .SelectMany(m => m.DropIds).ToList(); GContext.container.Resolve().AddItemByDropList(drops, null); GContext.Publish(new ShowData()); } return result; } public async Task DeleteMail(GameMail mail) { if (mail.IsDeleted) return false; var result = await UpdateMailState(new[] { mail }, EMailState.HasDeleted); if (result) _cache.Save(); return result; } public async Task DeleteMail(GameMail[] mails = null) { if (mails == null) { mails = _cache.GetAll() .Where(m => m.IsRead && m.HasReward) .ToArray(); } else { mails = mails.Where(m => !m.IsDeleted) .ToArray(); } if (mails.Length == 0) return false; var result = await UpdateMailState(mails, EMailState.HasDeleted); if (result) _cache.Save(); return result; } }