提交示例代码
This commit is contained in:
@@ -0,0 +1,225 @@
|
||||
using Fantasy.Async;
|
||||
using Fantasy.DataStructure.Collection;
|
||||
using Fantasy.Entitas.Interface;
|
||||
using Fantasy.Helper;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public class MailBoxManageComponentDestroySystem : DestroySystem<MailBoxManageComponent>
|
||||
{
|
||||
protected override void Destroy(MailBoxManageComponent self)
|
||||
{
|
||||
if (self.TimerId != 0)
|
||||
{
|
||||
self.Scene.TimerComponent.Net.Remove(ref self.TimerId);
|
||||
}
|
||||
|
||||
foreach (var (_, mailBox) in self.MailBoxes)
|
||||
{
|
||||
mailBox.Dispose();
|
||||
}
|
||||
|
||||
self.MinTime = 0;
|
||||
self.MailsByAccount.Clear();
|
||||
self.MailsByMailBoxType.Clear();
|
||||
self.Timers.Clear();
|
||||
self.TimeOutQueue.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public static class MailBoxManageComponentSystem
|
||||
{
|
||||
public static async FTask Init(this MailBoxManageComponent self)
|
||||
{
|
||||
// 获取数据库中所有的没有处理完成的MailBox
|
||||
|
||||
var mailBoxes = await self.Scene.World.DataBase.Query<MailBox>(d => true);
|
||||
|
||||
foreach (var mailBox in mailBoxes)
|
||||
{
|
||||
self.MailBoxes.Add(mailBox.Id, mailBox);
|
||||
|
||||
switch (mailBox.MailBoxType)
|
||||
{
|
||||
case MailBoxType.Specify:
|
||||
{
|
||||
foreach (var accountId in mailBox.AccountId)
|
||||
{
|
||||
self.MailsByAccount.Add(accountId, mailBox);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case MailBoxType.All:
|
||||
case MailBoxType.AllToDate:
|
||||
{
|
||||
self.MailsByMailBoxType.Add((int)mailBox.MailBoxType, mailBox);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.TimerId = self.Scene.TimerComponent.Net.RepeatedTimer(MailBoxManageComponent.MailCheckTIme, self.Timeout);
|
||||
}
|
||||
|
||||
private static void Timeout(this MailBoxManageComponent self)
|
||||
{
|
||||
var currentTime = TimeHelper.Now;
|
||||
|
||||
if (currentTime < self.MinTime)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查当然时候有过期的邮件箱需要处理
|
||||
|
||||
foreach (var (timeKey, _) in self.Timers)
|
||||
{
|
||||
if (timeKey > currentTime)
|
||||
{
|
||||
self.MinTime = timeKey;
|
||||
break;
|
||||
}
|
||||
|
||||
self.TimeOutQueue.Enqueue(timeKey);
|
||||
}
|
||||
|
||||
while (self.TimeOutQueue.TryDequeue(out var timeKey))
|
||||
{
|
||||
foreach (var mailBoxId in self.Timers[timeKey])
|
||||
{
|
||||
Log.Info($"MailBox:{mailBoxId} 过期了!");
|
||||
self.Remove(mailBoxId).Coroutine();
|
||||
}
|
||||
|
||||
self.Timers.RemoveKey(timeKey);
|
||||
}
|
||||
}
|
||||
|
||||
public static async FTask Remove(this MailBoxManageComponent self, long mailBoxId)
|
||||
{
|
||||
if (!self.MailBoxes.Remove(mailBoxId, out var mailBox))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 先删除按照分类存储的邮箱
|
||||
self.MailsByMailBoxType.RemoveValue((int)mailBox.MailBoxType, mailBox);
|
||||
// 删除个人邮件的邮件箱
|
||||
self.MailsByAccount.RemoveValue(mailBoxId, mailBox);
|
||||
// 在数据库中删除这个邮件
|
||||
await self.Scene.World.DataBase.Remove<MailBox>(mailBoxId);
|
||||
// 销毁这个MailBox
|
||||
mailBox.Dispose();
|
||||
}
|
||||
|
||||
public static async FTask GetHaveMail(this MailBoxManageComponent self, MailUnit mailUnit, bool sync)
|
||||
{
|
||||
var now = TimeHelper.Now;
|
||||
var worldDataBase = self.Scene.World.DataBase;
|
||||
var mailComponent = mailUnit.GetComponent<MailComponent>();
|
||||
|
||||
// 玩家领取范围邮件的逻辑处理
|
||||
|
||||
foreach (var (mailBoxType, mailBoxList) in self.MailsByMailBoxType)
|
||||
{
|
||||
using var removeMailBox = ListPool<MailBox>.Create();
|
||||
switch ((MailBoxType)mailBoxType)
|
||||
{
|
||||
// 发送给所有人的邮件
|
||||
case MailBoxType.All:
|
||||
{
|
||||
foreach (var mailBox in mailBoxList)
|
||||
{
|
||||
if (!mailBox.Received.Contains(mailUnit.Id))
|
||||
{
|
||||
// 如果是没有领取过这个邮件,首先要把自己添加到领取过的名单中。
|
||||
mailBox.Received.Add(mailUnit.Id);
|
||||
// 发送给自己的邮件列表里添加邮件。
|
||||
await mailUnit.GetComponent<MailComponent>().Add(MailFactory.Serializer.Clone(mailBox.Mail), true);
|
||||
}
|
||||
|
||||
if (mailBox.ExpireTime <= now)
|
||||
{
|
||||
// 邮件已经过期了,要进行清理这个邮件的操作了
|
||||
removeMailBox.Add(mailBox);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 保存邮件箱状态到数据库中。
|
||||
await worldDataBase.Save(mailBox);
|
||||
}
|
||||
|
||||
foreach (var mailBox in removeMailBox)
|
||||
{
|
||||
await self.Remove(mailBox.Id);
|
||||
}
|
||||
|
||||
// 这里有一个小的细节要处理,这里大家课下自己实现一下。
|
||||
break;
|
||||
}
|
||||
case MailBoxType.AllToDate:
|
||||
{
|
||||
foreach (var mailBox in mailBoxList)
|
||||
{
|
||||
Log.Debug($"mailBox.CreateTime >= mailUnit.CreateTime {mailBox.CreateTime} >= {mailUnit.CreateTime}");
|
||||
if (mailBox.CreateTime >= mailUnit.CreateTime && !mailBox.Received.Contains(mailUnit.Id))
|
||||
{
|
||||
// 如果是没有领取过这个邮件,首先要把自己添加到领取过的名单中。
|
||||
mailBox.Received.Add(mailUnit.Id);
|
||||
// 发送给自己的邮件列表里添加邮件。
|
||||
await mailUnit.GetComponent<MailComponent>().Add(MailFactory.Serializer.Clone(mailBox.Mail), true);
|
||||
}
|
||||
|
||||
if (mailBox.ExpireTime <= now)
|
||||
{
|
||||
// 邮件已经过期了,要进行清理这个邮件的操作了
|
||||
removeMailBox.Add(mailBox);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 保存邮件箱状态到数据库中。
|
||||
await worldDataBase.Save(mailBox);
|
||||
}
|
||||
|
||||
foreach (var mailBox in removeMailBox)
|
||||
{
|
||||
await self.Remove(mailBox.Id);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (self.MailsByAccount.TryGetValue(mailUnit.AccountId, out var mailBoxes))
|
||||
{
|
||||
using var removeMailBox = ListPool<MailBox>.Create();
|
||||
foreach (var mailBox in mailBoxes)
|
||||
{
|
||||
var cloneMail = MailFactory.Serializer.Clone(mailBox.Mail);
|
||||
await mailComponent.Add(cloneMail, sync);
|
||||
mailBox.AccountId.Remove(mailUnit.AccountId);
|
||||
Log.Debug($"领取了一个离线邮件 MailId:{cloneMail.Id}");
|
||||
|
||||
if (mailBox.AccountId.Count <= 0)
|
||||
{
|
||||
// 当邮件箱里没有要发送的玩家了,就表示这个邮件箱已经没有用处,可以删除了。
|
||||
removeMailBox.Add(mailBox);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var mailBox in removeMailBox)
|
||||
{
|
||||
await self.Remove(mailBox.Id);
|
||||
}
|
||||
|
||||
if (mailBoxes.Count <= 0)
|
||||
{
|
||||
// 如果MailsByAccount里的邮件箱已经没有邮件了,就删除这个邮件箱的缓存。
|
||||
self.MailsByAccount.RemoveByKey(mailUnit.AccountId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user